Java: почему двоичный ИЛИ не работает должным образом (см. Код ниже)? - PullRequest
1 голос
/ 21 апреля 2009

Я не понимаю вывод следующего кода:

public static void main(String[] args) {
    int i1, i2, i3, i4;
    byte b;
    i1 = 128;
    b = (byte) i1;
    i2 = (int) b;
    i3 = 0 | b;
    i4 = 1 << 7;
    System.out.format("i1: %d   b: %d   i2: %d   i3: %d   i4: %d\n", i1, b, i2, i3, i4);
}

Выход:

i1: 128   b: -128   i2: -128   i3: -128   i4: 128

Поскольку byte является 8-разрядным целым числом со знаком с добавлением двух , двоичные представления с 1 в старшем значащем бите интерпретируются как отрицательные значения, поэтому b становится -128 с которым у меня все в порядке. Я также понимаю, что, вероятно, хорошей идеей будет сохранять согласованность интерпретации при приведении, как с i2. Но не должны ли i3 и i4 иметь идентичные битовые комбинации и, следовательно, отображаться на идентичные int значения?

Ответы [ 7 ]

5 голосов
/ 21 апреля 2009

В этой строке:

i3 = 0 | b;

Переменная "b" автоматически повышается до типа int с расширением знака из-за оператора |, поэтому она становится (int)-128, т.е. 0xffffff80.

Когда "или" обнуляется, его значение остается прежним, а именно -128

4 голосов
/ 21 апреля 2009

Расширение знака - это то, что делает i2 и i3 отрицательными.

В выражении (0 | b), b повышен до int, и расширение знака происходит как часть этого продвижения.

Этого не происходит в выражении, присвоенном i4. Константы 1 и 7 уже являются целыми числами, поэтому расширение знака не используется.

4 голосов
/ 21 апреля 2009

Нет, i4 - это не байтовое значение, это int. Это означает, что его знаковый бит - это бит 31, а не бит 7.

ОБНОВЛЕНИЕ : i3 тоже int, но оно инициализируется расширением byte, поэтому он сохраняет знак от значения byte.

2 голосов
/ 21 апреля 2009

i2 = (int) b;

i3 = 0 | b;

оператор i3 эквивалентен:

i3 = 0 | ((int) b) = 0 | i2 поэтому, естественно, он будет иметь то же значение, что и i2

1 голос
/ 21 апреля 2009

Если вы хотите получить беззнаковое значение битовой комбинации в байте:

b & 0xff

См. Также этот старый ответ .

1 голос
/ 21 апреля 2009

Это просто. i3 = 0 | b; оценивается как byte, затем преобразуется в int. Принимая во внимание, что i4 = 1 << 7; оценит значение как int и присвоит его int. Итак, в первом случае мы получаем 10000000b приведение к int из byte, что даст нам -128. А во втором мы просто присваиваем это значение int без приведения, что дает нам 128.

1 голос
/ 21 апреля 2009

В

i3 = 0 | b;

Я угадываю 0 | Часть b оценивается как байт, а затем результаты преобразуются в int, а в

i4 = 1 << 7;

часть 1 << 7 уже является int. </p>

Вышеуказанное предположение было указано в комментариях как неверное!

Правильная версия: в верхнем выражении b уже приводится к int с расширением знака перед операцией OR.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...