【问题标题】:Why can't we shift an integer number more than the size of integer?为什么我们不能移动一个整数大于整数的大小?
【发布时间】:2021-06-06 03:10:33
【问题描述】:

在 GFG 上与 'Bitwise Operators' 相关的一个帖子中,写道,

如果数字的移位大于整数的大小,则 行为未定义。例如,如果是整数,则 1

但是当我尝试在 Java 中执行相同的操作时,我得到了以下结果,

1 1

1 2

1 4

1 8

而且这些结果也是合理的。由于整数是 32 位的,所以当我将 1 左移 32 位时,它会遍历所有 31 位并返回到第 0 位,因此我们得到值 1。对于

那结果怎么是未定义的呢? Java 不是 undefined 吗?

这是帖子的链接:https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/

【问题讨论】:

  • “未定义结果”表示您无法保证在这种情况下会发生什么。在不同的计算机、不同的虚拟机、不同版本的虚拟机上你可以得到不同的结果。例如,在您的环境中,您得到 1 1。但在另一个环境中,例如,它可以是 0(所有位都被移出,因此移到任何大于 31 的数字都将为零),等等。
  • 在 C 和 C++ 中,行为是未定义的,如 GFG 中所述。在 Java(这是一种完全不同的语言)中,行为在JLS - Shift Operators 中得到了很好的定义和描述。即,对于int 值,Java 仅使用最低 5 位,对于 long 值仅使用最低 6 位,这将移位计数减少到 int 的 0 到 31 和 long 的 0 到 63 的值。
  • "由于整数是 32 位的,所以当我将 1 左移 32 位时,它会遍历所有 31 位并返回到第 0 位,因此我们得到值 1。" : 不,那将是一个旋转操作。左移不是旋转操作,System.out.println(2 << 31); 打印 0 很容易显示,而旋转操作会打印 1。

标签: java data-structures dsa


【解决方案1】:

在 Java 中,当您移动 int 时,只考虑移位操作数的低 5 位。所以定义了行为,但它不希望它是你想要的。

这在语言规范https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.19 以及用于班次的虚拟机指令的定义中都有详细说明,如 ishl 此处:https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.ishl

至于为什么...这是因为 x86(我期待许多其他)CPU 的移位指令就是这样做的,而 Java 语言设计者不想增加开销来以另一种方式计算它。

因为他们实际定义了它,如果您在没有此问题的架构上运行 java,它将显式屏蔽移位中的较高位。 C 和 C++ 编译器未定义行为,因此他们的编译器永远不必这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多