在覈心Java VOLUME1書有一個警告說,說:什麼是模32或64的模?
小心:移位運算符的右手側參數減小模32 (除非左手側是一個長期的,在在這種情況下,右邊的模64被減少)。 例如,1 < < 35的值是相同的1 < < 3或8
究竟是什麼意思?爲什麼1變成8,而不是在35左移之後變成0?
許多感謝
在覈心Java VOLUME1書有一個警告說,說:什麼是模32或64的模?
小心:移位運算符的右手側參數減小模32 (除非左手側是一個長期的,在在這種情況下,右邊的模64被減少)。 例如,1 < < 35的值是相同的1 < < 3或8
究竟是什麼意思?爲什麼1變成8,而不是在35左移之後變成0?
許多感謝
在許多編程語言中,通過以上的大小移的數字數據類型(32位爲int,長爲64位)未定義。另一方面,Java將其定義爲使得(n << d)
等於(n << (d % 32))
,其中n
是int,而(n << d)
等於(n << (d % 64))
,其中n
是長的。
因此,1 << 35
相當於1 << (35 % 32)
,它等於1 << 3 = 8
。
減少模32的裝置(在其底部電平)你保持減去32,直到你有0到31(含)之間的一個數字。
換句話說:
actualValue = givenValue % 32;
的原因它,這是因爲它是沒有意義到32位移位32位值向左(或右),因爲它會總是是零(因爲你在一邊移動位,並在另一邊移動,-這樣做32次對32位值將導致零,無論你開始用什麼)。
因此對於Java整數(32位),31是明智的限制。長期(64位),63是明智的限制。
在你給的例子中,1 << 35
具有移位值從35降低到3(因爲35 % 32 == 3
)和1 < < 3是8:
Binary
0000 0001 (1 << 0) == 1
0000 0010 (1 << 1) == 2
0000 0100 (1 << 2) == 4
0000 1000 (1 << 3) == 8
||||
|||+--- 1
||+---- 2
|+----- 4
+------ 8
更簡潔
a << b
相同
a << (b & 31)
對於int類型。
不同的是,-1%32是-1,而-1 & 31是31和1 << -1 == 0x80000000
此行爲是在JLS 15.19
定義如果推動型的左側操作數的是int,只有右側操作數的五個最低位用作移位距離。就好像右側的操作數受掩碼值0x1f(0b11111)的按位邏輯AND運算符&(第15.22.1節)的處理。實際使用的換檔距離總是在0到31的範圍內。
如果左側操作數的升級類型很長,那麼只有右側操作數的最低六位用作移位距離。這是因爲如果在右邊的操作數進行逐位邏輯AND運算&(§15.22.1)與掩模的0x3F值(0b111111)。因此實際使用的換檔距離總是在0至63的範圍內(包括0和63)。
@ mug896它在JLS定義。更新了我的答案。 – 2014-04-02 16:49:34
有關詳細信息,語言參考:http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.19 – dsummersl 2012-02-01 22:04:29