今天看了一眼java.lang.Integer類的源碼,發現了這麼一句話:
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
乍看之下不懂啊。不過還好有上面那一句註釋。
好,來研究研究,我們知道,移位操作是直接操作的二進制數據,那麼爲什麼
((q << 6) + (q << 5) + (q << 2))
這麼移一下位就變成和 q * 100一樣的效果了呢。
我們來看看100這個數字的二進制是多少:1100100
總共7位,嗯。來,我們將之分離開來成爲:
1000000
0100000
0000000
0000000
0000100
0000000
0000000
這七組數據相加就是100,對吧?
好,1<<6 就是1000000,1<<5就是100000,同理1<<2就是100,其它爲0的位置,我們怎麼移都是0,所以不管了。
然後,我們 (1 << 6) + (1 <<5) + (1 << 2)就是100,得出來這個結果了嗎?
這個原理試用於所有正整數(負數及浮點數未測試)
好了,先原諒我沒學過計算機組成原理,操作系統神馬的。
從網上的資料和老師說的,都是說CPU沒有乘法運算指令的,都是用加法指令代替乘法運算。
所以移位運算應該會比乘法運算效率高。
下面我舉得例子不知道正確否,但是確實結果出了我的意料之外。
int num = 65536;
int res1 = 0;
int res2 = 0;
long start1 = System.currentTimeMillis();
for(int i = 0; i < Integer.MAX_VALUE; i++){
res1 = (65536 << 7) + (65536 << 3) + (65536 << 1) + (65536 << 0); // 實際上是 num * 139
}
long time1 = System.currentTimeMillis() - start1;
long start2 = System.currentTimeMillis();
for(int i = 0; i < Integer.MAX_VALUE; i++){
res2 = 65536 * 139;
}
long time2 = System.currentTimeMillis() - start2;
System.out.println(" time1:" + time1 + " \t res1:" + res1);
System.out.println(" time2:" + time2 + " \t res2:" + res2);
直接使用常量來計算,在這個例子中移位運算和乘法運算效率相差無幾。
但是如果將算式中的65536換成 num變量的話,就會發現乘法運算的效率會比移位運算快。而且是2-3倍。
常量運算結果:
變量運算結果:
期待高手解釋一下,感激不盡。