У меня следующий цикл:
for (byte i = 0 ; i < 128; i++) {
System.out.println(i + 1 + " " + name);
}
Когда я выполняю свою программу, он печатает все числа от -128 до 127 в бесконечном цикле. Почему это происходит?
У меня следующий цикл:
for (byte i = 0 ; i < 128; i++) {
System.out.println(i + 1 + " " + name);
}
Когда я выполняю свою программу, он печатает все числа от -128 до 127 в бесконечном цикле. Почему это происходит?
byte является 1-байтовым типом, поэтому может варьироваться от -128... 127, поэтому условие я < 128 всегда верно. Когда вы добавляете 1 к 127, он переполняется и становится -128 и т.д. В (бесконечном) цикле...
После 127, когда он увеличивается, он станет -128, поэтому ваше условие не будет соответствовать.
byte. Тип данных
byte
- это 8-разрядное двухзначное целое число. Он имеет минимальное значение-128
и максимальное значение127
(включительно). Тип данныхbyte
может быть полезен для экономии памяти в больших массивах, где действительно важна экономия памяти. Они также могут использоваться вместоint
, где их ограничения помогают уточнить ваш код; тот факт, что диапазон переменных ограничен, может служить формой документации.
Он будет работать следующим образом:
0, 1, 2, ..., 126, 127, -128, -127, ...
поскольку 8 бит могут представлять число с подписью до 127.
См. здесь для примитивных типов данных.
Изображение говорит больше, чем слова
Поскольку байты подписаны на Java, они всегда будут меньше 128.
Почему Java выбрал подписанные байты, это тайна из глубины времени. Я никогда не мог понять, почему они испортили совершенно отличный тип данных без знака: -)
Попробуйте это вместо:
for (byte i = 0 ; i >= 0; ++i ) {
или, еще лучше:
for (int i = 0 ; i < 128; ++i ) {
потому что, когда я == 127, и вы выполняете я ++, он переполняется до -128.
Тип байта имеет диапазон -128..127. Поэтому i
всегда меньше 128.
Хорошо, поэтому причина этого была уже решена, но в случае, если вас заинтересовал какой-то фон:
A bit
- наименьшая единица хранения, которую компьютер может распознать (n.b. не наименьшее число). Битом является либо 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)
.
Только представляя положительные числа (a unsigned byte
), мы можем представить 256 возможных чисел в диапазоне от 0
до 255
включительно.
Проблема возникает, когда мы хотим представлять подписанные данные. Наивный подход (n.b. для фона, а не для того, как это делает java) - взять левый бит и сделать его битом знака, где 1
отрицательный, а 0
- положительный. Так, например, 00010110
будет 21
, а 10010110
будет -21
.
Есть две основные проблемы с такой системой. Во-первых, 00000000
- это 0
, а 10000000
- -0
, но, как известно, нет -0
, который как-то отличается от 0
, но такая система допускает число и 0 ≠ -0
. Вторая проблема заключается в том, что из-за представления двух нулей система допускает только отображение чисел от -127
до 127
, диапазон только 254
(2
меньше, чем раньше).
Лучше система (и та, которая используется большинством систем) называется Two Compliment. В двух комплиментах положительные числа представлены с их нормальной битовой строкой, где самый левый бит равен 0. Отрицательные числа представлены с самым большим битом слева как 1, а затем вычисляются два комплимента для этого числа (откуда система получает свое имя )
Хотя математически это немного более сложный процесс, потому что мы имеем дело с числом 2
, есть короткие сокращения. По существу, вы можете взять положительную версию и (справа налево) взять все нули, пока не нажмете 1. Скопируйте эти нули и единицы, затем возьмите NOT
остальных бит. Так, например, чтобы получить -21
, положительный 21
равен 00010110
, мы берем 10
, а не остальные, чтобы получить 11101010
, два комплиментных представления -21
.
Два комплимента - это гораздо более сложная система для понимания, но она позволяет избежать ранее заявленных проблем, а для n-разрядного числа могут представлять все цифры от -2^(n-1)
до 2^(n-1)-1
, которые для нашего байта означают -128
127
(следовательно, проблема в этом вопросе)
Несколько заметок:
- Это только для целочисленного представления. Реальное представление чисел - это еще одна система целиком (если есть запрос на нее, я уверен, что мы могли бы сделать сообщение с номером CW)
- Wikipedia имеет пару систем представления чисел, если вам интересно.
Лучше всего, если вы делаете
for (byte i = 0 ; i < Byte.MAX_VALUE; i++ ) {
System.out.println( i + 1 + " " + name );
}
это должно работать
for (byte i = 0 ; i<128; ++i ) {
if(i==-128)
break;
System.out.println( i + 1 + " " + "name" );
}