Почему 11010100 << 1 равно 110101000, а не 10101000? - PullRequest
40 голосов
/ 20 февраля 2020

Почему, когда я пытаюсь сдвинуть биты для 11010100 2 , результат будет 110101000 2 , а не 10101000 2 .

int a = Integer.parseInt("11010100", 2) << 1;

Я пытаюсь сделать это:

int a = (byte)(Integer.parseInt("11010100", 2) << 1);

Но если выходное значение больше 128, все идет в минус, что логично. Как сделать так, чтобы количество бит не менялось?

Ответы [ 3 ]

61 голосов
/ 20 февраля 2020

Давайте сделаем это по одному шагу за раз.

  1. Integer.parseInt("11010100", 2) - это значение int 212. Это, кстати, не нужно; Вы можете просто написать: 0b11010100.

  2. 0b11010100 << 1 совпадает с 0b110101000 и составляет 424.

  3. Вы тогда приведите его к байту: (byte)(0b11010100 << 1). Биты после первых 8 все обрезаются, что оставляет 0b10101000, что составляет -88. Минус, да, потому что в java байты подписаны.

  4. Затем вы молча приводите этот -88 обратно к int, когда вы присваиваете ему значение int. Остается -88, что означает, что все старшие биты равны 1 с.

Следовательно, окончательное значение равно -88.

Если вы хотите увидеть 168 вместо этого (который является точно такими же битами, но показан без знака, а не со знаком), обычным приемом является использование & 0xFF, который устанавливает все биты, кроме первых 8, в 0, гарантируя, таким образом, положительное число:

byte b = (byte) (0b11010100 << 1);
System.out.println(b); // -88. It is not possible to print 168 when printing a byte.
int asUnsigned = b & 0xFF;
System.out.println(asUnsigned); // 168.

// or in one go:

System.out.println(((byte) (0b11010100 << 1)) & 0xFF); // 168

9 голосов
/ 20 февраля 2020

Если вы хотите установить на 0 все биты выше, чем нижние 8 бит, вы можете использовать побитовое И:

int a = (Integer.parseInt("11010100", 2) << 1) & 0xff;
System.out.println (Integer.toString(a,2));

Выход:

10101000
6 голосов
/ 20 февраля 2020

Попробуйте что-то вроде этого:

int anInt = Integer.parseInt("11010100", 2) << 1;
int asUnsignedInt= Byte.toUnsignedInt((byte) anInt);

toUnsignedInt введено в Java SE 8.

...