【问题标题】:Difference between >>> and >>>>> 和 >> 之间的区别
【发布时间】:2011-02-18 04:08:55
【问题描述】:

Java 中>>>>> 运算符有什么区别?

【问题讨论】:

标签: java syntax operators


【解决方案1】:

>> 是算术右移,>>> 是逻辑右移。

在算术移位中,符号位被扩展以保持数字的符号性。

例如:以 8 位表示的 -2 将是 11111110(因为最高有效位具有负权重)。使用算术移位将其右移一位会给你11111111,或-1。然而,逻辑右移并不关心该值是否可能表示一个有符号数。它只是将所有内容向右移动并从左侧填充 0。使用逻辑移位将我们的 -2 右移一位将得到01111111

【讨论】:

  • 虽然我同意并欣赏算术移位可以用于将有符号数乘以2^k,但我觉得奇怪的是这是每个人的答案。位串不是数字,>> 始终可以用于任何位串:无论位串扮演什么角色,也不管它是否有 ' 的概念,它总是做同样的事情标志'。当您的操作数 not 被解释为有符号数字时,可以通过讨论这种情况来扩展您已经很好的答案吗?我的投诉有道理吗?
  • 为什么说一串位不是数字?你会说十进制数字序列不是数字吗?
  • @danben 讨论它是否是数字只有在将其链接到上下文时才有意义。如果互联网只是电,那么我同意 String 只是一个数字。
  • @danben 但实际上,我认为 Ziggy 真正指的是(恕我直言),String 也可以被视为char[]。他并不是说char 不是数字;他只是说这是一个无符号数字。我认为这就是他迷路的地方。
  • @Ziggy 是对的:不是每个位串都是数字,也不是每个十进制数字序列都是数字。例如:电话号码、邮政编码(在许多国家/地区)等都是十进制数字字符串,但对它们进行加、减或乘是没有意义的,因此它们不是真正的数字。它们恰好是十进制数字字符串,但应该被视为字符串。 (加拿大和英国的邮政编码包含字母和数字。)
【解决方案2】:

>>> 是无符号移位;它将插入 0。>> 已签名,并将扩展符号位。

JLS 15.19 Shift Operators

移位运算符包括左移<<、有符号右移>>、无符号右移>>>

n>>s 的值是n 右移s 位位置,符号扩展

n>>>s 的值是n 右移s 位位置,零扩展名

    System.out.println(Integer.toBinaryString(-1));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >> 16));
    // prints "11111111111111111111111111111111"
    System.out.println(Integer.toBinaryString(-1 >>> 16));
    // prints "1111111111111111"

为了让事情更清楚,添加积极的对应物

System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"

由于它是正数,有符号和无符号移位都会在最左边添加 0。

相关问题

【讨论】:

  • 没有你的例子,我不会明白。
【解决方案3】:

它们都是右移,但>>>unsigned

来自documentation

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

【讨论】:

  • 你能举个例子解释一下吗
  • 我也觉得你应该举个例子。
  • 我想>>> 是未签名的,但为什么7>>32=7 呢?我运行了一个循环,一次只做一个班次,发现在32 班次之后,它又回到了7。唯一有意义的方法是,对于每个移出的数字,它都会进入一个“外圈”。在32 转移之后,它以某种方式回到了它的位置,但显然这仍然没有意义。怎么回事?
  • @IanLimarta 不是吗?我只得到 0。(for (int i = 7 << 1, j = 0; j < 32; j++) System.out.println(Integer.toString(i >>= 1, 2));) 如果您的意思是为什么 >>32 本身返回原始值,请参阅 this
  • 对不起。我的意思是为什么'7>>>32=7'。
【解决方案4】:

>>> 将始终在最左边放置一个 0,而>> 将根据其符号放置 1 或 0。

【讨论】:

    【解决方案5】:

    逻辑右移 (v >>> n) 返回一个值,其中v 中的位已右移n 位位置,0 从左侧移入。考虑移位 8 位值,用二进制编写:

    01111111 >>> 2 = 00011111
    10000000 >>> 2 = 00100000
    

    如果我们将这些位解释为无符号非负整数,则逻辑右移具有将数字除以相应 2 的幂的效果。但是,如果数字采用二进制补码表示,则逻辑右移不正确除负数。例如,当这些位被解释为无符号数时,上面的第二次右移将 128 移位到 32。但它会将 -128 转换为 32,这在 Java 中很典型,这些位以二进制补码形式解释。

    因此,如果要进行移位以除以 2 的幂,则需要算术右移 (v >> n)。它返回一个值,其中v 中的位已右移n 位位置,v 的最左边位 的副本从左侧移入: p>

    01111111 >> 2 = 00011111
    10000000 >> 2 = 11100000
    

    当位是二进制补码表示的数字时,算术右移具有除以 2 的幂的效果。这是有效的,因为最左边的位是符号位。除以 2 的幂必须保持符号相同。

    【讨论】:

      【解决方案6】:

      阅读更多关于Bitwise and Bit Shift Operators

      >>      Signed right shift
      >>>     Unsigned right shift
      

      位模式由左侧操作数给出,而要移位的位置数由右侧操作数给出。无符号右移运算符>>> 将一个移到最左边的位置

      >> 之后最左边的位置取决于符号扩展。

      简单来说>>>总是移到最左边的位置>>根据数字的符号进行移动,即1表示负数,0表示正数。


      例如,尝试使用负数和正数。

      int c = -153;
      System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
      System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
      System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
      System.out.println(Integer.toBinaryString(c <<= 2));
      
      System.out.println();
      
      c = 153;
      System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
      System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
      System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
      System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
      

      输出:

      11111111111111111111111111011001
      11111111111111111111111101100100
        111111111111111111111111011001
      11111111111111111111111101100100
      
                                100110
                              10011000
                                100110
                              10011000
      

      【讨论】:

      • 谢谢。只想添加注释以引用 Integer.MAX_VALUE、Integer.MIN_VALUE、-1、0、1 的位表示。例如:System.out.println(Integer.MAX_VALUE + ": " + String.format("%32s", Integer.toBinaryString(Integer.MAX_VALUE)).replace(' ', '0'))Integer.MAX_VALUE01111111111111111111111111111111; Integer.MIN_VALUE10000000000000000000000000000000; -111111111111111111111111111111111;000000000000000000000000000000000;100000000000000000000000000000001
      【解决方案7】:

      右移逻辑运算符 (&gt;&gt;&gt; N) 将位向右移动 N 个位置,丢弃符号位并用 0 填充最左边的 N 个位。例如:

      -1 (in 32-bit): 11111111111111111111111111111111
      

      &gt;&gt;&gt; 1 操作后变为:

      2147483647: 01111111111111111111111111111111
      

      右移算术运算符 (&gt;&gt; N) 也将位向右移动 N 个位置,但保留符号位并用 1 填充最左边的 N 个位。例如:

      -2 (in 32-bit): 11111111111111111111111111111110
      

      &gt;&gt; 1 操作后变为:

      -1: 11111111111111111111111111111111
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-25
        • 2020-05-10
        • 2014-09-20
        • 2010-10-28
        • 2015-10-04
        • 2012-08-12
        • 2019-12-21
        • 2018-01-18
        相关资源
        最近更新 更多