Java中负数偏移

5

我在Java中遇到了移位操作符的问题。我使用了以下代码,但无法理解该程序如何生成此输出。请指导我该程序如何生成此输出。

public class Operator {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int s = 8;
        s = s >>-63;
        System.out.println("value of i=" + s);
    }

}

输出: i的值为4

5个回答

19

根据JLS(Java语言规范)的第15.19节(位移操作符)

如果左操作数的提升类型为int,则只使用右操作数的五个最低位作为移位距离。就像右操作数受到按位逻辑AND运算符&(§15.22.1)与掩码值0x1f(0b11111)相同。因此,实际使用的移位距离始终在0到31之间,包括0和31。

现在 -63 & 0x1f == 1,因此实际上是向右移动了1位,因此答案为4。


谢谢您的回复,Jon。但是您能告诉我,我们如何识别这需要移位一位还是两位等等。所以请在这方面指导我。 - Dipu
1
@Dipu:你说的“认识到这必须向左移动一或两个”的意思是什么?你的问题非常不清楚-你没有告诉我们你想要实现什么。 - Jon Skeet
看见Jon,我想知道我们如何知道-63表示向左移动一位。所以可能有一些技巧。希望这能给你一个清晰的解释。 - Dipu
@Dipu - -63被表示为FFFFFFC1,当你执行AND操作时,你会得到FFFFFFC1 & 0x0000001f == 0x00000001这个计算结果。这个数字-63的表示方法是二进制补码。 - MByD
3
@Dipu:我在回答中明确说明了:规范指出“好像将右操作数与掩码值0x1f进行按位逻辑AND运算”,然后将其应用于您的示例:-63&0x1f为1。 - Jon Skeet
@JonSkeet 如果左操作数的类型是浮点型或双精度型呢? - user12208242

5

s = s >>-63;的作用和s = s >> 1;相似,仅仅是(-63 % 32)。

请参考JLS §15.19中的移位操作符行为


2

如果您想替换负移位,以下两个语句对于整数将产生相同的结果:

r << -shift

并且

r << ((32 - shift) % 32)

(32 是 Java 中整数的大小)


1
    int s=8;        
    Assert.assertEquals(s >>-63, s >>-63 % 32);
    Assert.assertEquals(s >>-63, s >>-31);
    Assert.assertEquals(s >>-31, s >>32 -31);
    Assert.assertEquals(s >>32 -31,s >>1); 
    Assert.assertEquals(s >>1,s /2); 
    Assert.assertEquals(s/24); 

1
使用-63进行移位实际上是使用-63&0x1f==1(对于int)或-63&0x3f==1(对于long)进行移位,因为在Java中使用>>左移时会使用符号扩展,在8的情况下,1将移出任何零位。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接