Как Java вычисляет отрицательные числа?

Я использую операцию ~ для манипуляции с битами, и мне просто интересно, как Java вычисляет отрицательное число?

Я проверил документацию по Java:

"Унарный оператор побитового дополнения" ~ "инвертирует бит-шаблон, он может применяться к любому из интегральных типов, делая каждый" 0 "a" 1 "и каждый" 1 "a" 0 ". Например, байт содержит 8 бит, применяя этот оператор к значению, бит-бит которого" 00000000 "изменит его шаблон на" 11111111".

Итак, если int a = 60 (0011 1100), то int c = ~a (1100 0011).

Вопрос в том, как Java вычисляет отрицательные числа так, чтобы 1100 0011 = -61? Вычисляется единственный способ 1100 0011 -61 is

  • старший бит - бит знака.
  • -2^6 + 2^1 + 2^0 = -61.

Но для меня это не имеет смысла.

Ответ 1

Предполагается, что старший бит является простым битом знака неправильным. Java, а также большинство современных языков программирования (и аппаратных архитектур) используют так называемое два дополнения для чисел. (Сам бит, по совпадению, указывает знак, но не так, как вы ожидали бы этого, т.е. 150 и -150 имеют больше различий, чем только знаковый бит в их представлении.)

Это представление может показаться странным выбором вначале, но на самом деле оно делает операции, такие как добавление положительного числа к отрицательному числу (или его вариациям), автоматически, без необходимости проверки процессором особых случаев.

Согласно соответствующая статья Википедии:

Система полезна для упрощения реализации арифметики на компьютерном оборудовании. Добавление 0011 (3) в 1111 (-1) сначала, кажется, дает неверный ответ 10010. Однако аппаратное обеспечение может просто игнорировать самый левый бит, чтобы дать правильный ответ 0010 (2). Должны выполняться проверки переполнения, чтобы выполнять операции, такие как суммирование 0100 и 0100. Таким образом, система позволяет добавлять отрицательные операнды без схемы вычитания и схему, которая обнаруживает знак числа. Кроме того, эта схема добавления также может вызывать вычитание, принимая два дополнения к числу (см. Ниже), что требует только дополнительного цикла или собственной схемы сумматора. Для этого схема просто притворяется, что существует дополнительный левый бит 1.

См. этот ответ для более подробного объяснения с большим количеством приятных и понятных примеров.

Ответ 2

Java примитивные числовые типы данных - int, long, byte и short представлены в два дополнения. Что это значит:

  • Самое высокое значение - результат всех битов, установленных в 1, кроме MSB.
    • Пример: 0111 1111 = 127
  • Значение MSB, равное 1, и все остальные биты, установленные в 0, являются самым низким значением.
    • Пример: 1000 0000 = -128

Единственное отрицательное значение здесь - MSB, поэтому, если мы разделим его на это представление, мы придем к -61:

|-128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|  1  |  1 | 0  |  0 | 0 | 0 | 1 | 1 |

-128 + 64 + 2 + 1 = -61.