Ответы:
Помните, что отрицательные числа хранятся как дополнение двух положительного аналога. В качестве примера, вот представление -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 - это двоичное значение
00000010
И ~ 2 переворачивает биты, поэтому значение теперь:
11111101
Который является двоичным представлением -3.
Как уже упоминалось, ~
только что перевернутые биты (меняются с одного на ноль и с нуля на один) и поскольку используется дополнение до двух, вы получите результат, который вы видели.
Одна вещь, которую нужно добавить, это то, почему используется дополнение до двух, так что операции с отрицательными числами будут такими же, как и с положительными числами. Подумайте о -3
числе, к которому 3
нужно прибавить, чтобы получить ноль, и вы увидите, что это число 1101
, помните, что двоичное сложение похоже на сложение в начальной школе (десятичное), только вы несете единицу, когда вы получаете два, а не 10 ,
1101 +
0011 // 3
=
10000
=
0000 // lose carry bit because integers have a constant number of bits.
Поэтому 1101
это -3
, флип биты , которые Вы получаете , 0010
который является два.
Я знаю, что ответ на этот вопрос опубликован давно, но я хотел бы поделиться своим ответом на то же самое.
Чтобы найти дополнение к числу, сначала найдите его двоичный эквивалент. Здесь десятичное число 2
представляется как 0000 0010
в двоичной форме. Теперь, взяв свое дополнение, инвертируя (переворачивая все 1 в 0 и все 0 в 1) все цифры своего двоичного представления, что приведет к:
0000 0010 → 1111 1101
Это дополнение к десятичному числу 2. А поскольку первый бит, т. Е. Бит знака, равен 1 в двоичном числе, это означает, что знак является отрицательным для числа, которое он сохранил. (здесь упомянутое число не 2, а дополнение к 2).
Теперь, поскольку числа хранятся в виде дополнения к 2 (принимая дополнение к числу плюс один), поэтому для отображения этого двоичного числа 1111 1101
в десятичном виде сначала нам нужно найти дополнение к его 2, которое будет:
1111 1101 → 0000 0010 + 1 → 0000 0011
Это дополнение 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 дополнение)
1000 0000 0000 0000 0000 0000 0101 теперь результат -5 проверить эту ссылку для видео <[Битовые операторы в Java] https://youtu.be/w4pJ4cGWe9Y
Просто ...........
Как 2-е дополнение любого числа мы можем вычислить, инвертируя все 1 с 0 и наоборот, чем мы добавляем 1 к нему.
Здесь N = ~ N дают результаты - (N + 1) всегда. Потому что система хранит данные в виде дополнения 2, что означает, что они хранят ~ N, как это.
~N = -(~(~N)+1) =-(N+1).
Например::
N = 10 = 1010
Than ~N = 0101
so ~(~N) = 1010
so ~(~N) +1 = 1011
Теперь точка откуда минус. Мое мнение: предположим, что у нас есть 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
. Положительные числа выводятся как есть.
Там есть внутреннее значение и его строковое представление. Для натуральных чисел они в основном совпадают:
irb(main):001:0> '%i' % 2
=> "2"
irb(main):002:0> 2
=> 2
Последнее эквивалентно:
irb(main):003:0> 2.to_s
"2"
~
переворачивает биты внутреннего значения. 2
есть 0b010
. ~2
есть 0b..101
. Две точки ( ..
) представляют бесконечное число 1
символов s. Поскольку старший значащий бит (MSB) результата равен 1
, результатом является отрицательное число ( (~2).negative? == true
). Для вывода отрицательного числа ruby
печатается -
, а затем два дополняют внутреннее значение. Два дополнения рассчитывается путем переворачивания битов, а затем сложения 1
. Два дополнения 0b..101
есть 3
. В качестве таких:
irb(main):005:0> '%b' % 2
=> "10"
irb(main):006:0> '%b' % ~2
=> "..101"
irb(main):007:0> ~2
=> -3
Подводя итог, он переворачивает биты, что меняет знак. Для вывода отрицательного числа он печатает -
, затем ~~2 + 1
( ~~2 == 2
).
Причина, по которой ruby
выводит отрицательные числа примерно так, заключается в том, что он обрабатывает сохраненное значение как дополнение к абсолютному значению. Другими словами, то , что хранится в 0b..101
. Это отрицательное число, и как таковое, это дополнение к некоторому значению x
. Чтобы найти x
, он делает два дополнения 0b..101
. Который является дополнением двух до двух x
. Который есть x
(например ~(~2 + 1) + 1 == 2
).
Если вы применяете ~
отрицательное число, оно просто переворачивает биты (что, тем не менее, меняет знак):
irb(main):008:0> '%b' % -3
=> "..101"
irb(main):009:0> '%b' % ~-3
=> "10"
irb(main):010:0> ~-3
=> 2
Что более запутанно, так это ~0xffffff00 != 0xff
(или любое другое значение с MSB, равным 1
). Давайте немного упростим это ~0xf0 != 0x0f
. Это потому, что это относится 0xf0
к положительному числу. Что на самом деле имеет смысл. Так, ~0xf0 == 0x..f0f
. Результатом является отрицательное число. Два дополнения 0x..f0f
есть 0xf1
. Так:
irb(main):011:0> '%x' % ~0xf0
=> "..f0f"
irb(main):012:0> (~0xf0).to_s(16)
=> "-f1"
Если вы не собираетесь применять побитовые операторы к результату, вы можете рассматривать их ~
как -x - 1
оператор:
irb(main):018:0> -2 - 1
=> -3
irb(main):019:0> --3 - 1
=> 2
Но это, возможно, не очень полезно.
Пример Предположим, у вас есть 8-битная (для простоты) сетевая маска, и вы хотите вычислить число 0
единиц. Вы можете вычислить их, щелкая битами и вызывая bit_length
( 0x0f.bit_length == 4
). Но ~0xf0 == 0x..f0f
мы должны отрезать ненужные биты:
irb(main):014:0> '%x' % (~0xf0 & 0xff)
=> "f"
irb(main):015:0> (~0xf0 & 0xff).bit_length
=> 4
Или вы можете использовать оператор XOR ( ^
):
irb(main):016:0> i = 0xf0
irb(main):017:0> '%x' % i ^ ((1 << i.bit_length) - 1)
=> "f"
Сначала мы должны разделить данную цифру на двоичные цифры, а затем повернуть ее, добавив последнюю двоичную цифру. После этого выполнения мы должны поставить знак противоположный предыдущей цифре, которую мы находим завершенной ~ 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 тильда (~) приводит данное значение к своему дополнению - все биты инвертированы. Это все, что делает тильда. Это не знак самоуверенного. Это не добавляет и не вычитает любое количество.
0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]
На стандартных процессорах для настольных компьютеров, использующих языки высокого уровня, такие как JavaScript, арифметика со знаком BASE10 является наиболее распространенной, но имейте в виду, что она не единственная. Биты на уровне ЦП подлежат интерпретации на основе ряда факторов. На уровне «кода», в данном случае JavaScript, они по определению интерпретируются как 32-разрядное целое число со знаком (давайте оставим поплавки вне этого). Думайте об этом как о кванте, эти 32 бита представляют множество возможных значений одновременно. Это полностью зависит от конвертирующего объектива, через который вы их просматриваете.
JavaScript Tilde operation (1's complement)
BASE2 lens
~0001 -> 1110 - end result of ~ bitwise operation
BASE10 Signed lens (typical JS implementation)
~1 -> -2
BASE10 Unsigned lens
~1 -> 14
Все вышесказанное является верным одновременно.