【问题标题】:Why does the right-shift operator produce a zero instead of a one?为什么右移运算符产生零而不是一?
【发布时间】:2010-06-09 16:35:15
【问题描述】:

我正在自学 Java,并完成 Thinking in Java 中的练习。

在第 116 页,练习 11,您应该将一个整数右移到其所有二进制位置,并使用 Integer.toBinaryString 显示每个位置。

public static void main(String[] args) {
int i = 8;
System.out.println(Integer.toBinaryString(i));
int maxIterations = Integer.toBinaryString(i).length();
int j;
for (j = 1; j < maxIterations; j++) {
    i >>= 1;
System.out.println(Integer.toBinaryString(i));
}

在解决方案指南中,输出如下所示:

1000
1100
1110
1111

当我运行这段代码时,我得到了这个:

1000
100
10
1

这里发生了什么。数字被截断了吗?

我正在使用 jdk1.6.0_20 64 位。本书使用jdk1.5 32bit。

【问题讨论】:

  • 您的结果是简单地右移数字的正确行为。 “解决方案”应该说明什么,我不明白。

标签: java bit-shift


【解决方案1】:

这本书好像有错误。

右移操作将所有位右移,移除最低有效位。如果您右对齐结果(例如,通过用零填充),这会更有意义。

00001000
00000100
00000010
00000001
00000000

移入的最高位是:

  • 0 如果你的号码是正数
  • 如果您的号码为负数,则为 1。

如果您希望最终结果为 1,请尝试使用负数,例如 -8 而不是 8。

11111111111111111111111111111000
11111111111111111111111111111100
11111111111111111111111111111110
11111111111111111111111111111111

如果您使用&gt;&gt;&gt; 而不是&gt;&gt;,则无论数字是正数还是负数,都将始终移入零。

【讨论】:

  • 这听起来不像书中的错误,如果您使用 4 位和 8 位,结果会有所不同(好吧,可能是一个错误,因为 Java 不允许您使用只有 4 位..).
【解决方案2】:

当给定一个正整数作为输入时,右移运算符最终产生零是正确的。

最好将其视为所有数字都向右移动,最右边的数字被切断并在左边添加一个额外的零的操作,即模式是:

00001000
00000100
00000010
00000001
00000000
00000000

【讨论】:

    【解决方案3】:

    来自位运算符Java Tutorials Page

    无符号右移运算符 >>>" 将零移到最左边 位置,而最左边的位置 “>>”之后取决于符号扩展。

    因为 8 是正数,所以偏移了一个零。如果i 为负数,则将移位一个(以保持整数上的符号相同)。

    【讨论】:

    • 但这并不能解释为什么如果我们移动 32 位 &gt;&gt; 32,我们会得到相同的数字!
    【解决方案4】:

    右移运算符将您的位向右移动,即

    01000
    00100
    00010
    00001
    

    右移将用与移位前相同的值“填充”最左边的位。 由于最左边的位是符号,所以正值将用 0 填充,负值将用 1 填充。

    【讨论】:

      【解决方案5】:

      如果您在 int 中设置最高位,例如

      int i = 1 << 31;
      

      您将看到所描述的行为,该标志将在轮班期间保留。 我认为这是一个旨在说明操作的示例。

      10000000000000000000000000000000
      11000000000000000000000000000000
      11100000000000000000000000000000
      11110000000000000000000000000000
      11111000000000000000000000000000
      11111100000000000000000000000000
      11111110000000000000000000000000
      ....
      11111111111111111111111111111000
      11111111111111111111111111111100
      11111111111111111111111111111110
      11111111111111111111111111111111
      

      【讨论】:

        【解决方案6】:

        您似乎认为variable &gt;&gt;= 1 将一个 1 转移到变量上。 1 实际上指定多少次 移动变量。有符号的数字在最高有效位的任何位置上移动。 &gt;&gt;&gt; 强制数字显示为无符号并始终移到零。

        【讨论】: