Почему ~ 2 равно -3? Как работает ~
оператор?
Почему ~ 2 равно -3? Как работает ~
оператор?
Помните, что отрицательные числа хранятся как дополнение двух положительного аналога. В качестве примера, вот представление -2 в дополнении к двум: (8 бит)
1111 1110
Чтобы получить это, нужно взять двоичное представление числа, взять его дополнение (инвертировать все биты) и добавить одно. Два начинается как 0000 0010, и инвертируя биты, мы получаем 1111 1101. При добавлении одного мы получим приведенный выше результат. Первый бит является знаковым битом, означающим отрицательный.
Итак, давайте посмотрим, как мы получим ~ 2 = -3:
Вот еще два:
0000 0010
Просто переверните все биты, и мы получим:
1111 1101
Ну, как выглядит -3 в дополнении к двум? Начните с положительного значения 3: 0000 0011, переверните все биты до 1111 1100 и добавьте один, чтобы получить отрицательное значение (-3), 1111 1101.
Так что, если вы просто инвертируете биты в 2, вы получите представление дополнения к -3.
~
переворачивает биты в значении.Почему
~2
это-3
связано с тем, как числа представляются поразрядно. Числа представлены как два дополнения .Итак, 2 - это двоичное значение
И ~ 2 переворачивает биты, поэтому значение теперь:
Который является двоичным представлением -3.
источник
Как уже упоминалось,
~
только что перевернутые биты (меняются с одного на ноль и с нуля на один) и поскольку используется дополнение до двух, вы получите результат, который вы видели.Одна вещь, которую нужно добавить, это то, почему используется дополнение до двух, так что операции с отрицательными числами будут такими же, как и с положительными числами. Подумайте о
-3
числе, к которому3
нужно прибавить, чтобы получить ноль, и вы увидите, что это число1101
, помните, что двоичное сложение похоже на сложение в начальной школе (десятичное), только вы несете единицу, когда вы получаете два, а не 10 ,Поэтому
1101
это-3
, флип биты , которые Вы получаете ,0010
который является два.источник
Эта операция является дополнением, а не отрицанием.
Считайте, что ~ 0 = -1, и работайте оттуда.
Алгоритм отрицания - «дополнение, приращение».
Вы знали? Существует также «поразрядное дополнение» , где обратные числа являются симметричными, и она имеет как 0 и -0.
источник
Я знаю, что ответ на этот вопрос опубликован давно, но я хотел бы поделиться своим ответом на то же самое.
Чтобы найти дополнение к числу, сначала найдите его двоичный эквивалент. Здесь десятичное число
2
представляется как0000 0010
в двоичной форме. Теперь, взяв свое дополнение, инвертируя (переворачивая все 1 в 0 и все 0 в 1) все цифры своего двоичного представления, что приведет к:Это дополнение к десятичному числу 2. А поскольку первый бит, т. Е. Бит знака, равен 1 в двоичном числе, это означает, что знак является отрицательным для числа, которое он сохранил. (здесь упомянутое число не 2, а дополнение к 2).
Теперь, поскольку числа хранятся в виде дополнения к 2 (принимая дополнение к числу плюс один), поэтому для отображения этого двоичного числа
1111 1101
в десятичном виде сначала нам нужно найти дополнение к его 2, которое будет:Это дополнение 2-х. Десятичное представление двоичного числа
0000 0011
, есть3
. И, поскольку бит знака был один, как упомянуто выше, итоговый ответ таков-3
.Подсказка: если вы внимательно прочитаете эту процедуру, то заметили бы, что результатом для оператора дополнения на самом деле является число (операнд - к которому применяется этот оператор) плюс единица со знаком минус. Вы можете попробовать это и с другими номерами.
источник
add, flip, add
.0010
->0011
->1100
->1101
0010
1101
0010
NOT 0 = 1
иNOT 1 = 0
. В четырехбитной системеNOT 0011
(3) =1100
(12 без знака, -4 со знаком). Из того, что я понимаю, дополнение к двум определяется как(NOT n) + 1
и используется для поиска отрицательного аналога числа независимо от количества бит. Таким образом,2c(5) = -5
. Видите, теперь это имеет смысл. Пока вы называете эту операцию тем, чем она является: побитовым НЕ.int a = 4; System.out.println (~ а); Результат будет: -5
'~' любого целого числа в java представляет собой 1 дополнение к no. например, я беру ~ 4, что означает в двоичном представлении 0100. во-первых, длина целого числа составляет четыре байта, то есть 4 * 8 (8 бит на 1 байт) = 32. Таким образом, в системной памяти 4 представлен как 0000 0000 0000 0000 0000 0000 0000 0100 теперь оператор ~ выполнит дополнение 1 к указанному выше двоичному номеру
то есть 1111 1111 1111 1111 1111 1111 1111 1011-> 1 дополняют наиболее значимый бит, представляющий знак «нет» (либо - или +), если он равен 1, то знак равен «-», если он равен 0, то знак равен «+» согласно этот наш результат - отрицательное число, в java отрицательные числа хранятся в форме дополнения 2, полученный результат мы должны преобразовать в дополнение 2 (сначала выполнить дополнение 1 и просто добавить дополнение 1 к 1). все единицы станут нулями, кроме старшего значащего бита 1 (который является нашим знаковым представлением числа, что означает оставшиеся 31 бит 1111 1111 1111 1111 1111 1111 1111 1011 (полученный результат оператора ~) 1000 0000 0000 0000 0000 0000 0000 0100 (1 дополнение)
1 (дополнение 2)
1000 0000 0000 0000 0000 0000 0101 теперь результат -5 проверить эту ссылку для видео <[Битовые операторы в Java] https://youtu.be/w4pJ4cGWe9Y
источник
Просто ...........
Как 2-е дополнение любого числа мы можем вычислить, инвертируя все 1 с 0 и наоборот, чем мы добавляем 1 к нему.
Здесь N = ~ N дают результаты - (N + 1) всегда. Потому что система хранит данные в виде дополнения 2, что означает, что они хранят ~ N, как это.
Например::
Теперь точка откуда минус. Мое мнение: предположим, что у нас есть 32-битный регистр, что означает 2 ^ 31 -1 бит, участвующий в работе, и оставшийся один бит, который изменяется в более ранних вычислениях (дополнении), сохраняется как знаковый бит, который обычно равен 1. И мы получаем результат как ~ 10 = -11.
~ (-11) = 10;
Вышесказанное верно, если printf ("% d", ~ 0); мы получаем результат: -1;
Но printf ("% u", ~ 0), чем результат: 4294967295 на 32-битной машине.
источник
Побитовый оператор дополнения (~) является унарным оператором.
Это работает согласно следующим методам
Сначала он преобразует данное десятичное число в соответствующее ему двоичное значение. То есть в случае 2 он сначала преобразует 2 в 0000 0010 (в 8-битное двоичное число).
Затем он преобразует все 1 в числе в 0, а все нули в 1, тогда число станет 1111 1101.
это представление дополнения 2 -3.
Чтобы найти значение без знака с помощью дополнения, то есть просто преобразовать 1111 1101 в десятичное (= 4294967293), мы можем просто использовать% u во время печати.
источник
Я думаю, что для большинства людей путаница возникает из-за разницы между десятичным числом и двоичным числом со знаком, поэтому давайте сначала поясним это:
для десятичного мира человека: 01 означает 1, -01 означает -1, для двоичного мира компьютера: 101 означает 5, если он не подписан. 101 означает (-4 + 1), если подписано, в то время как цифра со знаком находится в позиции x. | Икс
таким образом, бит 2 перевернутый = ~ 2 = ~ (010) = 101 = -4 + 1 = -3 путаница возникает из-за смешивания подписанного результата (101 = -3) и неопределяемого результата (101 = 5)
источник
TL; доктор
~
переворачивает биты. В результате знак меняется.~2
отрицательное число (0b..101
). Для вывода отрицательного числоruby
отпечатков-
, то двоичное дополнение~2
:-(~~2 + 1) == -(2 + 1) == 3
. Положительные числа выводятся как есть.Там есть внутреннее значение и его строковое представление. Для натуральных чисел они в основном совпадают:
Последнее эквивалентно:
~
переворачивает биты внутреннего значения.2
есть0b010
.~2
есть0b..101
. Две точки (..
) представляют бесконечное число1
символов s. Поскольку старший значащий бит (MSB) результата равен1
, результатом является отрицательное число ((~2).negative? == true
). Для вывода отрицательного числаruby
печатается-
, а затем два дополняют внутреннее значение. Два дополнения рассчитывается путем переворачивания битов, а затем сложения1
. Два дополнения0b..101
есть3
. В качестве таких:Подводя итог, он переворачивает биты, что меняет знак. Для вывода отрицательного числа он печатает
-
, затем~~2 + 1
(~~2 == 2
).Причина, по которой
ruby
выводит отрицательные числа примерно так, заключается в том, что он обрабатывает сохраненное значение как дополнение к абсолютному значению. Другими словами, то , что хранится в0b..101
. Это отрицательное число, и как таковое, это дополнение к некоторому значениюx
. Чтобы найтиx
, он делает два дополнения0b..101
. Который является дополнением двух до двухx
. Который естьx
(например~(~2 + 1) + 1 == 2
).Если вы применяете
~
отрицательное число, оно просто переворачивает биты (что, тем не менее, меняет знак):Что более запутанно, так это
~0xffffff00 != 0xff
(или любое другое значение с MSB, равным1
). Давайте немного упростим это~0xf0 != 0x0f
. Это потому, что это относится0xf0
к положительному числу. Что на самом деле имеет смысл. Так,~0xf0 == 0x..f0f
. Результатом является отрицательное число. Два дополнения0x..f0f
есть0xf1
. Так:Если вы не собираетесь применять побитовые операторы к результату, вы можете рассматривать их
~
как-x - 1
оператор:Но это, возможно, не очень полезно.
Пример Предположим, у вас есть 8-битная (для простоты) сетевая маска, и вы хотите вычислить число
0
единиц. Вы можете вычислить их, щелкая битами и вызываяbit_length
(0x0f.bit_length == 4
). Но~0xf0 == 0x..f0f
мы должны отрезать ненужные биты:Или вы можете использовать оператор XOR (
^
):источник
Сначала мы должны разделить данную цифру на двоичные цифры, а затем повернуть ее, добавив последнюю двоичную цифру. После этого выполнения мы должны поставить знак противоположный предыдущей цифре, которую мы находим завершенной ~ 2 = -3 Объяснение : 2s двоичная форма - 00000010, изменения - 11111101, это дополнение к ним, затем дополненное 00000010 + 1 = 00000011, что является двоичной формой из трех и с -sign Ie, -3
источник
Побитовый оператор - это унарный оператор, который работает по методу знака и величины согласно моему опыту и знаниям.
Например, ~ 2 приведет к -3.
Это связано с тем, что побитовый оператор сначала должен представлять число в знаке и амплитуде, равное 0000 0010 (8-битный оператор), где MSB является знаковым битом.
Затем позже будет принято отрицательное число 2, которое равно -2.
-2 представляется как 1000 0010 (8-битный оператор) по знаку и величине.
Позже он добавляет 1 к LSB (1000 0010 + 1), что дает вам 1000 0011.
Который -3.
источник
Javascript тильда (~) приводит данное значение к своему дополнению - все биты инвертированы. Это все, что делает тильда. Это не знак самоуверенного. Это не добавляет и не вычитает любое количество.
На стандартных процессорах для настольных компьютеров, использующих языки высокого уровня, такие как JavaScript, арифметика со знаком BASE10 является наиболее распространенной, но имейте в виду, что она не единственная. Биты на уровне ЦП подлежат интерпретации на основе ряда факторов. На уровне «кода», в данном случае JavaScript, они по определению интерпретируются как 32-разрядное целое число со знаком (давайте оставим поплавки вне этого). Думайте об этом как о кванте, эти 32 бита представляют множество возможных значений одновременно. Это полностью зависит от конвертирующего объектива, через который вы их просматриваете.
Все вышесказанное является верным одновременно.
источник
В основном, действие - это дополнение, а не отрицание.
Здесь x = ~ x дают результаты - (x + 1) всегда.
х = ~ 2
- (2 + 1)
-3
источник