java移位运算_Java移位运算符 “
詳解
首先舉一個樣例來說明不是循環(huán)移位:
假設(shè)上面的程序改為
i = 3L << 63
程序的結(jié)果仍然為
1000000000000000000000000000000000000000000000000000000000000000
那么就說明Java中的移位運(yùn)算不是循環(huán)的。
那對上面的問題又怎么解釋呢?
在JLS(Java Language Specific 15.19)中有例如以下解釋:If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.
If the promoted type of the left-hand operand is long, then only the six lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x3f (0b111111). The shift distance actually used is therefore always in the range 0 to 63, inclusive.
意思是說:在移位運(yùn)算中,假設(shè)被移位的操作數(shù)是int類型的,那么僅僅會用到移位數(shù)的最低5位,假設(shè)是long類型的,那么僅僅會用到低六位。
那么為什么是低5位和低6位呢?相信你應(yīng)該明確了,int共占32位,long占64位,正好是2的5次冪和6次冪。能夠理解為分別對32 和 64 取模。所以1L << 64 就會變成 1L << 0。結(jié)果自然就是1了。
關(guān)于網(wǎng)上的說法:
網(wǎng)上有很多資料說上述定義是由編譯器完畢的,即假設(shè)寫 1L << 64 。則編譯器會將文件編譯為 ?1L << 0 。可是經(jīng)過本人的實(shí)驗(yàn)發(fā)現(xiàn)這個過程會發(fā)生在執(zhí)行時而不是編譯位class文件的過程。以下是個人所做的一些實(shí)驗(yàn)。
實(shí)驗(yàn)過程:
將程序編譯為class文件
使用javap輸出class文件的內(nèi)容
使用HSDIS輸出虛擬機(jī)執(zhí)行的匯編代碼
源程序:
public class SF{
public static void main(String[] args) {
new SF().sh(1,2);
}
public int sh(int a , int b){
return (a << 32);
}
}
注意此處使用的是int類型
在windows環(huán)境下的批處理文件
javac SF.java
javap -verbose SF > sfp.txt
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp -XX:CompileCommand=dontinline,*SF.sh -XX:CompileCommand=compileonly,*SF.sh SF > sfasm.txt
pause
這里須要用到HSDIS插件才干輸出匯編代碼。
以下是javap的結(jié)果。
iload_1 為取得參數(shù)a,在棧中push ?32 ?后,進(jìn)行移位操作。ishl中的i指代的是int的移位操作。
再看反匯編的輸出:
[Verified Entry Point]
0x01c92e50: mov %eax,-0x4000(%esp)
0x01c92e57: push %ebp
0x01c92e58: sub $0x18,%esp ;*iload_1
; - SF::sh@0 (line 7)
0x01c92e5b: shl $0x0,%edx
0x01c92e5e: mov %edx,%eax
0x01c92e60: add $0x18,%esp
0x01c92e63: pop %ebp
0x01c92e64: test %eax,0x140100 ; {poll_return}
看到在分配完??臻g后,在0x01c92e5b這一行中,進(jìn)行了移位。操作數(shù)為0x0
總結(jié)
以上是生活随笔為你收集整理的java移位运算_Java移位运算符 “的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab数字图像处理-找不同
- 下一篇: 修正读取ISO中文命名的FatmsMod