首頁  >  問答  >  主體

Java中的整型移位操作,为什么是“只有数值右端的低5位才有用”?

大家好,最近在看《Java编程思想》,在第三章“操作符”中有这么一段:

如果对char、byte或者short类型的数值进行移位处理,那么在移位进行之前,它们会被转成int类型,并且得到的结果也是一个int类型的值。只有数值右端的低5位才有用。这样可防止我们移位超过init型值所具有的位数。(译注:因为2的5次方为32,而int型值只有32位。

之后google查到了这篇文章:http://blog.csdn.net/showershow/article/details/6959122,不过还是没懂。

虽然译者做了注解,不过我还是不明白,为什么是“只有数值右端的低5位才有用”?有谁能够解释一下吗?谢谢!

PS. 第一次来这里,发现编辑器竟然支持Markdown,非常不错!

PHP中文网PHP中文网2765 天前712

全部回覆(4)我來回復

  • 高洛峰

    高洛峰2017-04-17 11:26:27

    一看到你的問題,我也不理解這句話。所以我寫了一個簡單的程式來看位移操作用的是什麼 bytecode :

    public class Test {
        public static void main(String[] args) {
            byte b = 32;
            int i = b << 4;
            System.out.println(i);
        }
    }
    

    用 javap 看編譯出來的字節碼:

      public static void main(java.lang.String[]);
        Code:
           0: bipush        32
           2: istore_1
           3: iload_1
           4: iconst_4
           5: ishl
           6: istore_2
           7: getstatic     #2                  // Field java/lang/System.out:Ljava/
    io/PrintStream;
          10: iload_2
          11: invokevirtual #3                  // Method java/io/PrintStream.printl
    n:(I)V
          14: return
    }
    

    我發現用的是 ishl ,它的解釋是這樣的:http://cs.au.dk/~mis/dOvs/jvmspec/ref-_ishl.html

    Shifts value2 left by the amount indicated in the five low bits of value1

    所以我終於明白英文原文裡的“right-hand side”指的並不是某個數值的“右端”,“right-hand side”是一個術語,應該翻譯成“右操作數”。

    Only the five low-order bits of the right-hand side will be used.

    這句話可以做這樣的理解:位移運算子只用到了它的右邊操作數的低5位。

    我看到這句話的時候就理解成只使用了左操作數的低5位,可能你也是這樣理解的。

    P.S. 在 wiki 上翻到:http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_Java

    only the five lowest-order bits of the right-hand operand are used as the shift distance

    這裡使用「right-hand operand」更明確地表示是右手邊的運算元。

    回覆
    0
  • 怪我咯

    怪我咯2017-04-17 11:26:27

    題主可能理解錯了。

    a = b << c  
    

    規範中說的 只有數值右端的低5位才有用 說的是 c

    我們先看 b,在計算過程中,b 被轉換成 int,因為 int 類型是 32 位,也就是 b 的值最多可以移動 31 位。

    如果把 b 移動 33 位,只有最後的 5 位有效,於是:

    (為了方便測試,一下程式碼為 js 程式碼)

    50 << 33
    // output:100
    

    等價於

    50 << (33%32)
    // output:100
    

    也就是

    50 << 1
    // output:100
    

    為了嚴謹,題主自行在 java 中測試。

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-17 11:26:27

    因為int只有32位,<< 32就溢出了呀。所以限制為最右邊那5位,以防溢出( 2 ** 5 = 32 )。

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 11:26:27

    我的理解是這樣的,java程式設計思想是說的>>>這個無符號的右移為運算子的右邊數值不能大於31,例如int i = -1,i >>> 33裡面的數值右端指的是33這個數值。即取33的低位1[0 0001],所以只往右移動一位

    回覆
    0
  • 取消回覆