Как работает побитовый оператор дополнения (~ тильда)? - PullRequest
163 голосов
/ 26 апреля 2009

Почему ~ 2 равно -3? Как работает оператор ~?

Ответы [ 13 ]

256 голосов
/ 26 апреля 2009

Помните, что отрицательные числа хранятся как два дополнения положительного аналога. В качестве примера, вот представление -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.

Оператор дополнения (~) просто переворачивает биты. Именно машина должна интерпретировать эти биты.

35 голосов
/ 26 апреля 2009

~ переворачивает биты в значении.

Почему ~2 означает -3 связано с тем, как числа представляются поразрядно. Числа представлены в виде дополнения до двух .

Итак, 2 - двоичное значение

00000010

И ~ 2 переворачивает биты, поэтому значение теперь равно:

11111101

Что является двоичным представлением -3.

15 голосов
/ 27 апреля 2009

Как уже упоминалось, другие ~ просто переворачивают биты (изменяет один на ноль, а ноль на один), и поскольку используется дополнение к двум , вы получаете результат, который вы видели.

Одна вещь, которую нужно добавить, это , почему используется дополнение к двум, так что операции с отрицательными числами будут такими же, как и с положительными числами. Думайте о -3 как о числе, к которому нужно добавить 3, чтобы получить ноль, и вы увидите, что это число равно 1101, помните, что двоичное сложение похоже на сложение в начальной школе (десятичное число), только вы несете один, когда вы добираетесь до двух, а не 10.

 1101 +
 0011 // 3
    =
10000
    =
 0000 // lose carry bit because integers have a constant number of bits.

Поэтому 1101 равно -3, переверните биты, которые вы получите 0010, что равно двум.

8 голосов
/ 27 апреля 2009

Эта операция является дополнением, а не отрицанием.

Считайте, что ~ 0 = -1, и работайте оттуда.

Алгоритм отрицания: «дополнение, приращение».

Знаете ли вы? Существует также «дополнение», в котором обратные числа симметричны , и оно имеет 0 и -0.

5 голосов
/ 04 апреля 2014

Я знаю, что ответ на этот вопрос опубликован довольно давно, но я хотел бы поделиться своим ответом на этот же вопрос.

Чтобы найти дополнение к числу, сначала найдите его двоичный эквивалент. Здесь десятичное число 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

Это дополнение к двум. Десятичное представление двоичного числа, 0000 0011, равно 3. И, поскольку бит знака был один, как упомянуто выше, итоговый ответ - -3.

Подсказка: Если вы внимательно прочитаете эту процедуру, то заметили бы, что результатом для оператора дополнения на самом деле является число (операнд - к которому применяется этот оператор) плюс единица с отрицательный знак Вы можете попробовать это и с другими номерами.

4 голосов
/ 14 июля 2017

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 0100 (1 дополнение)

1 (дополнение 2)

1000 0000 0000 0000 0000 0000 0000 0101 теперь результат -5 проверьте эту ссылку для видео <[Битовые операторы в Java] <a href="https://youtu.be/w4pJ4cGWe9Y" rel="nofollow noreferrer">https://youtu.be/w4pJ4cGWe9Y

2 голосов
/ 23 декабря 2014

Просто ...........

Как дополнение 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-битной машине.

1 голос
/ 09 февраля 2017

Я думаю, что для большинства людей путаница возникает из-за разницы между десятичным числом и двоичным числом со знаком, поэтому давайте сначала уточним:

для десятичного мира человека: 01 означает 1, -01 означает -1, для двоичного мира компьютера: 101 означает 5, если он не подписан. 101 означает (-4 + 1), если подписано, в то время как цифра со знаком находится в позиции x. | х

так что бит 2 перевернутый = ~ 2 = ~ (010) = 101 = -4 + 1 = -3 путаница возникает из-за смешения подписанного результата (101 = -3) и неопределяемого результата (101 = 5)

1 голос
/ 18 сентября 2015

Оператор побитового дополнения (~) является унарным оператором.

Работает по следующим методам

Сначала он преобразует данное десятичное число в соответствующий двоичный файл значение. В случае 2 сначала преобразуется из 2 в 0000 0010 (в 8-разрядное двоичное число).

Затем он преобразует все 1 из числа в 0 и все нули в 1, тогда число станет 1111 1101.

это представление дополнения к 2 -3.

Чтобы найти значение без знака с помощью дополнения, т.е. просто чтобы преобразовать 1111 1101 в десятичную (= 4294967293), мы можем просто использовать% u во время печати. ​​

0 голосов
/ 30 апреля 2019

В основном действие - это дополнение, а не отрицание.

Здесь x = ~ x дает результаты - (x + 1) всегда.

х = ~ 2

- (2 + 1) * +1013 *

-3

...