为什么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位?
jhamon

1
字节a = ...将对其进行修复。
Perdi Estaquel

Answers:


61

让我们一次迈出一步。

  1. Integer.parseInt("11010100", 2)-这是int值212。顺便说一下,这是不必要的;您可以只写:0b11010100

  2. 0b11010100 << 1与相同0b110101000,为424。

  3. 然后,将其转换为一个字节:(byte)(0b11010100 << 1)。超出前8位的所有位都将丢失,从而留下0b10101000,即-88。减,是的,因为在Java中字节是带符号的。

  4. 然后,当您将其分配给int值时,将其-88静默转换为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

如果要将所有高于后8位的位都设置为0,则可以按位与:

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);

Java SE 8中引入了toUnsignedInt

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.