Хорошо, поэтому причина этого уже была решена, но на случай, если вас заинтересовал какой-то фон:
A bit
- это наименьшая единица памяти, которую может распознать компьютер (например, не наименьшее число). Бит это либо 0
, либо 1
.
A byte
- это 8-битный тип данных, то есть он состоит из 8-битных строк, таких как 10101010
или 0001110
. Используя простую комбинаторику, мы знаем, что существует 2^8 = 256
возможных комбинаций байтов.
Если бы мы хотели представлять только положительные числа, мы могли бы выполнить прямое преобразование из базы 2 в базу 10. Это работает для битовой строки b7b6b5b4b3b2b1b0
, число в десятичной дроби равно dec = sum from n=0 to 7 of (bn * 2^n)
.
Представляя только положительные числа (unsigned byte
), мы можем представить 256 возможных чисел в диапазоне от 0
до 255
включительно.
Проблема возникает, когда мы хотим представить подписанные данные. Наивный подход (н.б. это для фона, а не для java) - взять самый левый бит и сделать его знаковым битом, где 1
отрицательно, а 0
положительно. Так, например, 00010110
будет 21
, а 10010110
будет -21
.
Есть две основные проблемы с такой системой. Во-первых, 00000000
- это 0
, а 10000000
- это -0
, но, как все знают, нет -0
, который каким-то образом отличается от 0
, но такая система учитывает число и 0 ≠ -0
. Вторая проблема заключается в том, что из-за представления двух нулей система допускает только представление чисел от -127
до 127
, диапазон которых составляет всего 254
(2
меньше, чем прежде).
Гораздо лучшая система (и та, которую использует большинство систем) называется Two's Compliment . В комплименте Two положительные числа представлены их обычной строкой битов, где крайний левый бит равен 0. Отрицательные числа представлены самым левым битом как 1, а затем вычисляется комплимент двоих для этого числа (откуда система получает свое имя )
Хотя математически это немного более сложный процесс, потому что мы имеем дело с числом 2
, но есть несколько коротких путей. По сути, вы можете взять положительную версию и (справа налево) взять все нули, пока не достигнете 1. Скопируйте эти нули и один, а затем возьмите NOT
оставшихся битов. Так, например, чтобы получить -21
, положительное 21
равно 00010110
, мы берем 10
, а не остальное, чтобы получить 11101010
, комплимент для двух -21
.
Compliment Two - гораздо более сложная для понимания система, но она позволяет избежать ранее заявленных проблем и для n-битного числа может представлять все цифры от -2^(n-1)
до 2^(n-1)-1
, что для нашего байта означает от -128
до 127
(отсюда и проблема в этом вопросе)
Пара заметок:
- Это только для целочисленного представления. Представление действительных чисел - это совсем другая система (если есть запрос, я уверен, что мы могли бы сделать сообщение о числовом представлении CW)
- В Википедии есть еще пара систем представления чисел, если вам интересно.