移位操作和乘法的比較

今天看了一眼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倍。

常量運算結果:

變量運算結果:


期待高手解釋一下,感激不盡。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章