java - Java奇怪程序输出中的移位运算符

标签 java

我遇到了以下程序,它的行为方式出乎意料。

public class ShiftProgram
{
      public static void main(String[] args)
      {
             int i = 0;
             while(-1 << i != 0)
                   i++;
             System.out.println(i);
      }
}

如果我们考虑这个程序的输出,当它达到 32 时,while 循环条件应该返回 false 并终止,它应该打印 32。

如果你运行这个程序,它不会打印任何东西,而是进入一个无限循环。知道发生了什么事吗?先感谢您。

最佳答案

您是否尝试过在循环中打印出 (-1 << i) 以查看出了什么问题?如果你这样做,你会看到它发生了:

-1 << 0 = -1
-1 << 1 = -2
-1 << 2 = -4
-1 << 3 = -8
-1 << 4 = -16
-1 << 5 = -32
-1 << 6 = -64
-1 << 7 = -128
-1 << 8 = -256
-1 << 9 = -512
-1 << 10 = -1024
-1 << 11 = -2048
-1 << 12 = -4096
-1 << 13 = -8192
-1 << 14 = -16384
-1 << 15 = -32768
-1 << 16 = -65536
-1 << 17 = -131072
-1 << 18 = -262144
-1 << 19 = -524288
-1 << 20 = -1048576
-1 << 21 = -2097152
-1 << 22 = -4194304
-1 << 23 = -8388608
-1 << 24 = -16777216
-1 << 25 = -33554432
-1 << 26 = -67108864
-1 << 27 = -134217728
-1 << 28 = -268435456
-1 << 29 = -536870912
-1 << 30 = -1073741824
-1 << 31 = -2147483648
-1 << 32 = -1
-1 << 33 = -2
-1 << 34 = -4
-1 << 35 = -8
-1 << 36 = -16
[.. etc ..]

根据 language specification :

The value of n<<s is n left-shifted s bit positions; this is equivalent (even if overflow occurs) to multiplication by two to the power s.

...所以结果将始终为负数。

该文档还告诉您:

If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f. The shift distance actually used is therefore always in the range 0 to 31, inclusive.

因此,如果您使用 32 的移位,则会被解释为 32 & 0x1f 的移位,即 0 。由 -1 移动的 0 仍然只是 -1 ,而不是 0

关于java - Java奇怪程序输出中的移位运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5202308/

相关文章:

java - 需要帮助使用 Java 高级 REST 客户端批量 API 创建动态 Elasticsearch 索引

java - 在 Java 中尝试 Catch block

java - 读取方法中返回的ArrayList - java

java - Web 服务器上的文本到图像

java - 在 Java 语言层次结构中添加自定义树类

java - 给定正数的所有数字之和

java - 使用 jasper 报告或 iText for Java 打印页面大小(20.5 x 14 厘米)的自定义发票

java - Hibernate SessionFactory getCurrentSession 在没有 Activity 事务的情况下无效

java - Android Jack mockito 替代品

Java Collection-Within-Collection 并发