移位操作和乘法的比较

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

常量运算结果:

变量运算结果:


期待高手解释一下,感激不尽。

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