Почему оператор сдвига вправо выдает ноль вместо единицы? - PullRequest
3 голосов
/ 09 июня 2010

Я учу себя Java, и я выполняю упражнения по мышлению на Java.

На упражнении 11 на странице 116 вы должны сместить вправо целое число через все его двоичные позиции и отобразить каждую позицию с помощью Integer.toBinaryString.

public static void main(String[] args) {
int i = 8;
System.out.println(Integer.toBinaryString(i));
int maxIterations = Integer.toBinaryString(i).length();
int j;
for (j = 1; j < maxIterations; j++) {
    i >>= 1;
System.out.println(Integer.toBinaryString(i));
}

В руководстве по решению вывод выглядит следующим образом:

1000
1100
1110
1111

Когда я запускаю этот код, я получаю это:

1000
100
10
1

Чтоздесь происходитЦифры обрезаны?

Я использую jdk1.6.0_20 64bit.Книга использует jdk1.5 32bit.

Ответы [ 6 ]

9 голосов
/ 09 июня 2010

Похоже, что в книге есть ошибка.

Операция сдвига вправо сдвигает все биты вправо, удаляя младший значащий бит.Это имеет больше смысла, если вы правильно выровняете результаты (например, заполняя нулями).

00001000
00000100
00000010
00000001
00000000

Самый верхний бит сдвинут в:

  • 0, если вашчисло положительное
  • 1, если ваше число отрицательное.

Если вы хотите, чтобы конечный результат был равен единице, попробуйте использовать отрицательное число, например -8 вместо 8.

11111111111111111111111111111000
11111111111111111111111111111100
11111111111111111111111111111110
11111111111111111111111111111111

Если вы используете >>> вместо >>, то ноль всегда будет сдвигаться независимо от того, является ли число положительным или отрицательным.

3 голосов
/ 09 июня 2010

Из побитовых операторов Страница учебных пособий по Java :

Оператор правого сдвига без знака «>>>» сдвигает ноль в крайнее левое положение положение, в то время как крайнее левое положение после «>>» зависит расширение знака.

Так как 8 положительно, ноль смещен. Если бы i было отрицательным, вместо него получалось бы смещение (чтобы сохранить тот же знак на целом числе).

3 голосов
/ 09 июня 2010

Правильно, что оператор сдвига вправо в конечном итоге выдает ноль, когда в качестве входных данных задано положительное целое число.

Лучше всего рассматривать это как операцию, в которой все цифры сдвинуты вправо, крайняя правая цифра обрезана и добавлен дополнительный ноль влево, т.е.*

2 голосов
/ 09 июня 2010

Оператор сдвига вправо перемещает ваши биты вправо, т.е.

01000
00100
00010
00001

Сдвиг вправо «заполнит» крайний левый бит тем же значением, которое было до сдвига. А поскольку крайний левый бит является знаком, положительное значение будет заполнено нулями, а отрицательное - единицами.

1 голос
/ 09 июня 2010

Вы, кажется, думаете, что variable >>= 1 сдвигает единицу на переменную.1 фактически указывает , сколько раз смещает переменную.Числа со знаком сдвигаются на все, что находится в наиболее значимой битовой позиции.>>> заставляет число действовать без знака и всегда сдвигаться на нули.

1 голос
/ 09 июня 2010

Если вы установите старший бит в вашем int как

int i = 1 << 31;

Вы увидите описанное поведение, знак будет сохраняться во время смены.Я предполагаю, что это был пример, предназначенный для иллюстрации операции.

10000000000000000000000000000000
11000000000000000000000000000000
11100000000000000000000000000000
11110000000000000000000000000000
11111000000000000000000000000000
11111100000000000000000000000000
11111110000000000000000000000000
....
11111111111111111111111111111000
11111111111111111111111111111100
11111111111111111111111111111110
11111111111111111111111111111111
...