【问题标题】:Why does 11010100 << 1 equal 110101000, not 10101000?为什么 11010100 << 1 等于 110101000,而不是 10101000?
【发布时间】:2020-02-20 13:53:50
【问题描述】:

为什么当我尝试为 110101002 移位时,结果是 1101010002,而不是 101010002

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

我尝试这样做:

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

但如果输出值大于 128,则一切都变为负数,这是合乎逻辑的。 我怎样才能使那个位数不改变?

【问题讨论】:

  • 整数运算总是在ints 或longs 上完成。
  • 您使用的是整数,它们是 32 位长。为什么你会期望结果被截断为 8 位?
  • byte a = ... 会修复它。

标签: java bit-shift


【解决方案1】:

让我们一步一步来。

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

  2. 0b11010100 &lt;&lt; 10b110101000一样,都是424。

  3. 然后将其转换为一个字节:(byte)(0b11010100 &lt;&lt; 1)。前 8 位之外的位都被删除,剩下 0b10101000,即 -88。减号,是的,因为在 java 中字节是有符号的。

  4. 然后,当您将它分配给一个 int 值时,您会默默地将这个 -88 转换回 int。它仍然是 -88,这意味着所有的高位都是 1。

因此,最终值为-88

如果您想查看168(完全相同的位,但显示为无符号而不是有符号),通常的技巧是使用&amp; 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

【讨论】:

  • 他将值存储在int a,所以如果你有&amp; 0xFF,那么你根本不需要转换。 int a = (0b11010100&lt;&lt; 1) &amp; 0xFF;
【解决方案2】:

如果你想将所有高于底部 8 位的位设置为 0,你可以使用逐位与:

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

输出:

10101000

【讨论】:

    【解决方案3】:

    试试这样的:

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

    toUnsignedInt 已在 Java SE 8 中引入。

    【讨论】:

      猜你喜欢
      • 2015-08-28
      • 2013-08-17
      • 2014-07-04
      • 2015-04-08
      • 1970-01-01
      • 2019-06-06
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      相关资源
      最近更新 更多