java -1>>>1_关于java:为什么1 >> 32 == 1?

我想知道这是否是JVM错误?

Java版本" 1.6.0_0"

OpenJDK运行时环境(IcedTea6 1.4.1)(6b14-1.4.1-0ubuntu13)

OpenJDK 64位服务器VM(内部版本14.0-b08,混合模式)

class Tmp {

public static void main(String[] args) {

System.out.println("1>>1 ="+(1>>1));

System.out.println("1>>2 ="+(1>>2));

System.out.println("1>>31 ="+(1>>31));

System.out.println("1>>32 ="+(1>>32));

System.out.println("1>>33 ="+(1>>33));

}

}

当我运行它时会产生这个:

1>>1 = 0

1>>2 = 0

1>>31 = 0

1>>32 = 1

1>>33 = 0

对于32的任意倍数,我也得到相同的结果。

我是否需要编写自己的右移按钮来检查这一点?

bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/601266请保持更新。

回复@Arthur:好像是的,您需要编写自己的右移按钮以检查此情况。

rwong:那是我的错误,我将其删除。 尽管我仍然认为它是"错误的数学",但这不是编译器错误。

另请参见C#/ Java之类的高级语言屏蔽位移计数操作数的原因是什么?

+1感谢您提出的问题,从不知道这一点。 :)

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.22.1

15.19移位运算符

如果左侧操作数的提升类型为int,则仅将右侧操作数的最低5位用作移位距离。就像右侧操作数受到掩码值0x1f的按位逻辑AND运算符&(§15.22.1)一样。因此,实际使用的移动距离始终在0到31(含)范围内。

如果左侧操作数的提升类型很长,则仅将右侧操作数的六个最低阶位用作移位距离。就像右侧操作数受到掩码值0x3f的按位逻辑AND运算符&(§15.22.1)一样。因此,实际使用的移动距离始终在0到63之间(包括0和63)。

(强调我的)

这不是错误。在n >> m中,它仅查看m的最后五位-因此,大于31的任何数字都将减少为mod 32的数字。因此,(256 >> 37) == 8为true。

编辑:如果您正在使用int,则为true。如果很长,则它会查看m的最后六位,或以64为单位的mod。

那么(1 >> 32)变成(1 >> 0)? 奇怪的。

+1。 您可能需要引用JLS 15.19。

对此感到有点难过。 Java为什么用这种方式定义它。 我认为C ++实际上采取了额外的步骤(CPU指令)来解决这一问题。 该决定似乎源于具有十年历史的微处理器。

@rwong,又错了。 C ++说:"如果右操作数为负,或者大于或等于提升后的左操作数的位长度,则该行为是不确定的。" 这意味着,如果您这样做(1 >> 33),您就会向鼻恶魔敞开大门。 Java比C ++更具体,而不是更少。

我认为(-9%9)== 4在C ++中足够奇怪了。 (我知道原因,但仍然很有趣)

@Vuntic:int c =((unsigned int)-9)%((unsigned int)9);

@rwong(-9%9)为0。在数学和C ++中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值