Здравствуйте, Vamp, Вы писали:
V>Здравствуйте, Аноним, Вы писали:
А>>Как работает операция дополнения? ~ (тильда)
V>"Но я надеюсь, нет я просто уверен" (С), что она выполняет дополнение. Хотя на самом деле это операция побитового НЕ.
Немного теории множеств
Пусть задано множество M битов, установленых в 1, принадлежащее множеству A установленных в 1 всех битов некоторого интегрального типа.
Тогда дополнением (это такой термин из Т.М. множества M до множества A будет такое множество !M установленных в 1 битов, что
1) пересечение множеств M и !M пусто.
2) объединение множеств M и !M есть множество A.
Операция ~ есть операция получения из множества M множества !M и обратно (Доказательство очевидно. Привести?)
Откуда семантически следует, что операцию ~ можно называть операцией дополнения.
Прямой ответ на вопрос: операция ~ сбрасывает все установленные биты в 0 и устанавливает все сброшенные биты в 1.
unsigned char a = 0xAA; // бинарное 10101010
a = ~a; // a == 0x55; бинарное 01010101
Здравствуйте, Astaroth, Вы писали:
A>Здравствуйте, <Аноним>, Вы писали:
А>>Как работает операция дополнения? ~ (тильда)
A>00 1 A>01 0 A>10 0 A>11 1
Долго думал что это
Даже заглянул в справочник по мат. логике.
Такого так нет
Вообще-то это отрицание xor-а
Но! Фишка в том, что операция ~ — унарная
Здравствуйте, Аноним, Вы писали:
А>Как работает операция дополнения? ~ (тильда)
C сабжем согласен
А операция ~ инвертирует каждый бит аргумента
(в противовес — операция ! инвертирует младший бит аргумента, а остальные биты обнуляет)
На счет названия "дополнение": именно побитно инвертированное слово будет дополнением аргумента
до нуля, т.е. X + ~X = 0,хотя м.б. я и ошибаюся
SW>>Прямой ответ на вопрос: операция ~ сбрасывает все установленные биты в 0 и устанавливает все сброшенные биты в 1.
А>То есть это то же самое что и xor 1111...11 А>А что быстрее ~x или x^0xFF... ?
Конечно первое, так как команда xor — двухадресная, а команда not — одноадресная.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
В догонку к предидущему ответу:
Стандарт читать полезно, прежде чем в математические и семантические дебри вдаваться:
"The operand of ~ shall have integral or enumeration type; the result is the one's complement of it's operand". 5.3.1/9
Английским языком сказано complement — дополнение
SW>>Прямой ответ на вопрос: операция ~ сбрасывает все установленные биты в 0 и устанавливает все сброшенные биты в 1. А>То есть это то же самое что и xor 1111...11
То же, да не то... Узнать сколько поставить FF-ов и FF-ов ли — вопрос не тривиальный. Размер интегральных типов жестко не установлен. (См. тред "размер char в битах" в этом форуме).
А>А что быстрее ~x или x^0xFF... ?
Я не знаю. Но глубоко убеждён, что оптимизатор сгенерирует на оба случая одинаковый код.
Здравствуйте, bugmonster, Вы писали:
B>Здравствуйте, Аноним, Вы писали:
А>>Как работает операция дополнения? ~ (тильда)
B>C сабжем согласен B>А операция ~ инвертирует каждый бит аргумента B>(в противовес — операция ! инвертирует младший бит аргумента, а остальные биты обнуляет)
К сожалению это не так. Контрпример:
unsigned char a = 0x10;
a = !a;
По вашему a должно принять значение 0x01, однако оно принимает значение 0x00;
Попробую это объяснить. Оператор ! работает только с операндами типа bool. Оператор ! возвращает true в случае false и false в случае true. Если операнд имеет другой тип, с ним происходит implicit conversion (неявное преобразование) к типу bool. Результат оператора ! имеет тип bool. Стандарт, 5.3.1/8
Implicit conversion к типу bool происходит по следующему правилу: 0 приобразуется к false, любое другое значение — к true. Стандарт, 4.12/1
Потом в приведённом примере происходит implicit conversion результата оператора ! к интегральному типу. Оно происходит по следующиму правилу: false преобразуется к 0, true к 1. Стандарт, 4.7/14
То-есть, "на самом деле", если перейти к explicit conversion (явному преобразованию), этот пример представится в виде
unsigned char a = 0x10;
a = static_cast<unsigned char>(!static_cast<bool>(a)); // Стандарт, 5.4
Подробней — читайте стандарт.
Сорри за, возможно, излишний бюрократизм.
B>На счет названия "дополнение": именно побитно инвертированное слово будет дополнением аргумента B>до нуля, т.е. X + ~X = 0,хотя м.б. я и ошибаюся
Опять же, к сожалению, это не так. Я раскрывал этот вопрос в этой теме.
SW>По вашему a должно принять значение 0x01, однако оно принимает значение 0x00;
Как раз по-моему оно должно принимать значение 0х00, а 0x01 будет принимать в случае оператора ~,
так-что или вы не так поняли или я не так объяснял
SW>Попробую это объяснить. Оператор ! работает только с операндами типа bool.
Неправда. Более того оператор ! появился задолго до bool, исчо в С (а bool только несколько лет назад).
Просто для оператора ! существут два значения — нулевое и ненулевое.
SW>Сорри за, возможно, излишний бюрократизм.
Сорри, за излишнюю простоту
B>>На счет названия "дополнение": именно побитно инвертированное слово будет дополнением аргумента B>>до нуля, т.е. X + ~X = 0,хотя м.б. я и ошибаюся SW>Опять же, к сожалению, это не так. Я раскрывал этот вопрос в этой теме.
Чо-то не раскрылось. Ответ я взял из глубинных залежей мозга, времен обучения схемотехнике в УПК .
Смысл его состоит в том, что если к биту прибавить единичку, то он поменяет свое значение.
Пример:
0+1=1
1+1=0 + признак переноса в старший разряд
SW>>По вашему a должно принять значение 0x01, однако оно принимает значение 0x00; B>Как раз по-моему оно должно принимать значение 0х00, а 0x01 будет принимать в случае оператора ~, B>так-что или вы не так поняли или я не так объяснял
Вы писали "B>(в противовес — операция ! инвертирует младший бит аргумента, а остальные биты обнуляет"
Младший бит 0x10 — 0. Инвертируем, получаем 0x11. Обнуляем остальные, в результате получаем 0x01.
SW>>Попробую это объяснить. Оператор ! работает только с операндами типа bool. B>Неправда.
Правда в том смысле, что он свой операнд неявно преобразует к bool и, таким образом, работает только с операндами типа bool. "The operand of the logical nagation operator ! is implicitly converted to bool". Стандарт, 5.3.1/8 B>Более того оператор ! появился задолго до bool, исчо в С (а bool только несколько лет назад).
Оператор ! появился задолго до C. Я говорю о С++. Но даже в С он, к сожалению, работает не так, как описали вы.
B>Просто для оператора ! существут два значения — нулевое и ненулевое.
В С++ — true и false.
B>>>На счет названия "дополнение": именно побитно инвертированное слово будет дополнением аргумента B>>>до нуля, т.е. X + ~X = 0,хотя м.б. я и ошибаюся SW>>Опять же, к сожалению, это не так. Я раскрывал этот вопрос в этой теме. B>Чо-то не раскрылось. Ответ я взял из глубинных залежей мозга, времен обучения схемотехнике в УПК . B>Смысл его состоит в том, что если к биту прибавить единичку, то он поменяет свое значение. B>Пример: B>0+1=1 B>1+1=0 + признак переноса в старший разряд
Да, с некоторыми оговорками, это так. X, насколько я понимаю, у вас имеет интегральный тип? В случае X + ~X каждому биту-единичке в X противостоит бит-нолик в ~X. Таким образом X + ~X != 0, более того во всех битах результата будут единички.
Здравствуйте, Sir Wiz, Вы писали:
SW>Вы писали "B>(в противовес — операция ! инвертирует младший бит аргумента, а остальные биты обнуляет" SW>Младший бит 0x10 — 0. Инвертируем, получаем 0x11. Обнуляем остальные, в результате получаем 0x01.
Вот как раз здесь я неправильно выразился , 0x10 — ненулевое значение и превратится оно в 0,
а я имел ввиду, что оператор ! из 0 делает 1.
SW>Оператор ! появился задолго до C. Я говорю о С++. Но даже в С он, к сожалению, работает не так, как описали вы.
А я пишу об операторе !, который в С/С++ работает именно так как я сказал (заметьте, я писал как он работает
на самом деле, и не тыкал пальцем в стандарты С++)
B>>Просто для оператора ! существут два значения — нулевое и ненулевое. SW>В С++ — true и false.
true и false есть только в С++ и только как значения bool. Вообще-то мы пишем про одно и то-же, только я имею
ввиду физический уровень (нолики-единички-регистры-защелки), а вы теорию С++.
B>>Пример: B>>0+1=1 B>>1+1=0 + признак переноса в старший разряд SW>Да, с некоторыми оговорками, это так. X, насколько я понимаю, у вас имеет интегральный тип? В случае X + ~X каждому биту-единичке в X противостоит бит-нолик в ~X. Таким образом X + ~X != 0, более того во всех битах результата будут единички.
Я не зря упомянул схемотехник: 0 и 1 — значения двоичного сигнала хранящегося в одном бите регитра процессора,
без всяких оговорок.
А в случае с X-ами я опять-таки неправильно выразился: имелось ввиду что в дополнительном коде ~(X-1) = -X,
а т.к. X + (-X) = 0, то X + ~(X+1) = 0
Здравствуйте, Vamp, Вы писали:
V>А зачем со мной спорить?
Проблемы перевода с понятного на русский . Фраза:
"V>"Но я надеюсь, нет я просто уверен" (С), что она выполняет дополнение. Хотя на самом деле это операция побитового НЕ."
Прозвучала для моего возбуждённого жарой уха как:
"Операция дополнения (я надеюсь, нет я просто уверен) выполняет операцию дополнения, а вот ~ это операция побитового НЕ."
V>Я это все и не собирался отрицать. Просто я пытался объяснить, что такое "дополнение".
А я и не спорил, значит, я основу подводил
Здравствуйте, bugmonster, Вы писали:
B>А я пишу об операторе !, который в С/С++ работает именно так как я сказал (заметьте, я писал как он работает B>на самом деле, и не тыкал пальцем в стандарты С++)
Оператор ! "на самом деле" должен работать в С++ так, как написано в стандарте С++, а в С — так, как написано в стандарте С.
B>true и false есть только в С++ и только как значения bool.
В java их нет? Фраза формально не верна.
B>Вообще-то мы пишем про одно и то-же, только я имею B>ввиду физический уровень (нолики-единички-регистры-защелки), а вы теорию С++.
Исключительно практику. Стандарт это практика. Я его изучаю. Отвечая на такие темы изучаю. Это моя методология, если позволите.
Для успешного продолжения имения в вашем виду физического уровня и во избежание ошибок, советую прочитать трехтомник П.Хоровица, У.Хилла "Искусство схемотехники"
SW>>Да, с некоторыми оговорками, это так. X, насколько я понимаю, у вас имеет интегральный тип? В случае X + ~X каждому биту-единичке в X противостоит бит-нолик в ~X. Таким образом X + ~X != 0, более того во всех битах результата будут единички. B>Я не зря упомянул схемотехник: 0 и 1 — значения двоичного сигнала хранящегося в одном бите регитра процессора, B>без всяких оговорок.
На физическом уровне есть значение ("состояние" — верный термин) Z — состояние высокого импеданса. Оговорка?
B>А в случае с X-ами я опять-таки неправильно выразился: имелось ввиду что в дополнительном коде ~(X-1) = -X, B>а т.к. X + (-X) = 0, то X + ~(X+1) = 0
"Дополнительном коде"?! Речь о дополнении. Простом дополнении из теории множеств. Простом дополнении из дискретной математики.
Страну в которой установки, выданные УПК легко ставятся в контраргумент формализованному стандарту, утверждённому комитетом ANSI, ISO, IEC, принятому де-факто практически всеми корпоративными разработчиками П.О., не победить. И "тыкаю" я в стандарт потому, что хочу иметь уверенность в том, что то, что я говорю — формально верно.