Подтвердить что ты не робот

Неожиданный бесконечный байтовый цикл

У меня следующий цикл:

for (byte i = 0 ; i < 128; i++) {
    System.out.println(i + 1 + " " + name);
}

Когда я выполняю свою программу, он печатает все числа от -128 до 127 в бесконечном цикле. Почему это происходит?

4b9b3361

Ответ 1

byte является 1-байтовым типом, поэтому может варьироваться от -128... 127, поэтому условие я < 128 всегда верно. Когда вы добавляете 1 к 127, он переполняется и становится -128 и т.д. В (бесконечном) цикле...

Ответ 2

После 127, когда он увеличивается, он станет -128, поэтому ваше условие не будет соответствовать.

byte. Тип данных byte - это 8-разрядное двухзначное целое число. Он имеет минимальное значение -128 и максимальное значение 127 (включительно). Тип данных byte может быть полезен для экономии памяти в больших массивах, где действительно важна экономия памяти. Они также могут использоваться вместо int, где их ограничения помогают уточнить ваш код; тот факт, что диапазон переменных ограничен, может служить формой документации.


Он будет работать следующим образом:

0, 1, 2, ..., 126, 127, -128, -127, ...

поскольку 8 бит могут представлять число с подписью до 127.

См. здесь для примитивных типов данных.


Изображение говорит больше, чем слова alt text

Ответ 3

Поскольку байты подписаны на Java, они всегда будут меньше 128.

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

Попробуйте это вместо:

for (byte i = 0 ; i >= 0; ++i ) {

или, еще лучше:

for (int i = 0 ; i < 128; ++i ) {

Ответ 4

потому что, когда я == 127, и вы выполняете я ++, он переполняется до -128.

Ответ 5

Тип байта имеет диапазон -128..127. Поэтому i всегда меньше 128.

Ответ 6

Хорошо, поэтому причина этого была уже решена, но в случае, если вас заинтересовал какой-то фон:

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 имеет пару систем представления чисел, если вам интересно.

Ответ 7

Лучше всего, если вы делаете

for (byte i = 0 ; i < Byte.MAX_VALUE; i++ ) {
  System.out.println( i + 1 + " " + name );
}

Ответ 8

это должно работать

        for (byte i = 0 ; i<128; ++i ) {
        if(i==-128)
            break;
        System.out.println( i + 1 + " " + "name" );
    }