不需要的Java移位行为 [英] Unwanted Java bitshift behavior

查看:61
本文介绍了不需要的Java移位行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为正在执行的某些计算生成位掩码,在这里我需要屏蔽一个int,以便除x最右边的位以外的所有其他位都变为零.我这样做是:

I'm generating bitmasks for some calculations I'm doing, where I need to mask an int such that all except the x rightmost bits become zero. I do this using:

int mask = ~(-1 << x);

这对于x的所有值(x = 32除外)都很好.它应该返回-1,但返回0.这是怎么回事?

This works fine for all values of x except for x = 32. It should return -1 then, but it returns 0. What is happening here?

我也尝试过:

int mask = -1 >>> 32 - x;

在x = 0时,它应该返回0,但返回-1.以某种方式将某物移位32会使操作返回到运算符的左侧.当我尝试将-1移位33或34位时,它会返回一个值,好像它移位了1或2.我是否正确假设Java确实执行了以下操作:

At x = 0 it should return 0, yet it returns -1. Somehow shifting something by 32 causes the operation to return the left side of the operator. When I try shifting -1 by 33 or 34 bits it returns a value as if it shifted by 1 or 2. Am I correct in assuming Java actually does something like this:

int mask = ~(-1 << x % 32);

int mask = -1 >>> (32 - x) % 32;

?

如果是这样,如果您超过int的32位长度,为什么还要循环这种行为? Oracle上的文档明确指出:

If so, why would you want this loop around behavior if you go above the 32 bit length of the int? The documentation on Oracle clearly states:

无符号右移运算符">>>"将一个零移位到 最左边的位置

The unsigned right shift operator ">>>" shifts a zero into the leftmost position

但是很明显,当偏移量必须超过32时,这实际上不是它的工作.

But clearly that's not actually what it's doing when it has to shift by more than 32...

推荐答案

是的,您是正确的;在应用之前,先将偏移量修改32(对于long,则修改为64).

Yes, you're correct; shifts are modded by 32 (or 64, for longs) before they're applied.

JLS 15.19 :

如果左侧操作数的提升类型为int,则仅将右侧操作数的最低5位用作移位距离.就像右手操作数受到了按位逻辑AND运算符&的约束. (§15.22.1),其掩码值为0x1f(0b11111).因此,实际使用的移位距离始终在0到31之间,包括端值.

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 (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.

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

If the promoted type of the left-hand operand is long, then only the six 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 0x3f (0b111111). The shift distance actually used is therefore always in the range 0 to 63, inclusive.

关于为什么 Java选择了此行为,我对您没有任何建议.

As to why Java chose this behavior, I don't have any advice for you.

这篇关于不需要的Java移位行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆