Чому 11010100 << 1 дорівнює 110101000, а не 10101000?


40

Чому, коли я намагаюся змінити біти на 11010100 2 , результат 110101000 2 , а не 10101000 2 .

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

Я намагаюся це зробити:

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

Але якщо значення виходу більше 128, все переходить у мінус, що логічно. Як зробити так, щоб кількість бітів не змінювалося?


4
Арифметика цілого числа завжди виконується на ints або longs.
Том Хотін - тайклін

34
Ви використовуєте цілі числа, довжина яких становить 32 біти. Чому ви очікуєте, що результат буде скорочений до 8 біт?
джемон

1
байт a = ... це виправить.
Перді Естакель

Відповіді:


61

Давайте зробимо це покроково.

  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

19
Він зберігає цінність у int a, тому якщо у вас є & 0xFF, то вам взагалі не потрібно робити передачу. int a = (0b11010100<< 1) & 0xFF;
Mooing Duck

9

Якщо ви хочете встановити на 0 всі біти вище, ніж нижній 8 біт, ви можете використовувати розрядний І:

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

Вихід:

10101000

6

Спробуйте щось подібне:

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

toUnsignedInt було введено в Java SE 8.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.