这篇文章主要介绍了Java怎么用位运算实现乘法运算的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java怎么用位运算实现乘法运算文章都会有所收获,下面我们一起来看看吧。
十进制相乘
例如,
26 * 15,在进行乘法操作时,我们一般这样算,先用
5乘以
6得到
30,把
0写下把
3记在一边,再用
5乘以
2得到
10再加上之前的
3写在下面,得到
130;计算完
5再计算
1分别乘以
6和
2把得到的结果
26记在下面,然后把
130和
26相加(有错位)得到
390。
二进制相乘
看完了十进制的相乘,再来看下二进制的相乘,基本原理是一样的,也是以十字相乘法为例,计算
5 * 7。
5的二进制为
101,
7的二进制为
111,来看下二进制的十字相乘法。
可以看到二进制为
101和二进制
111用传统的方式来计算,得到的结果为
100011,而二进制
100011对应的十进制为
35。
所以说,在计算的过程中,十进制和二进制的计算方式是一样的,当然这里就不进行举例和证明了。
思路分析
既然计算过程有了,那么怎么样用代码来实现呢?
我们再来看下上图中二进制的计算过程:
先用二进制
111的最后一位
1乘上
101得到
101。
再用二进制
111的倒数第2位
1乘上
101得到
101。
再用二进制
111的倒数第3位
1乘上
101得到
101。
得到的三个
101进行二进制相加,得到
100011。
注意,第
2步和第
3步得到的结果
101都往前挪了一位,相当于
1010和
10100,也就是最后相加的计算为:
10100 + 1010 + 101 = 100011。
再来看得到最终相加的计算
10100 + 1010 + 101 = 100011,也就是只要我们找到如何把数据转换为几位数的相加就可以了,因为之前已经实现了如何用位运算实现加法操作。
这三个数
101、
1010、
10100的数量刚好与二进制
111的个数相同,也就是二进制(上图下面那个乘数
111)有几位就会产生几个数相加,如果是与
11111相乘就会产生
5个数相加。
再来看数据之前的关系:
第一次相乘结果:
101 = 101 + 0
第二次相乘结果:
1111 = 101 < 1 + 101 = 1010 + 101
第三次相乘结果:
100011 = 101 < 2 + 1111 = 10100 + 1010 + 101
从这里我们可以看到,每计算一次,
101只需要向左移一次再加上上一次的计算结果就可以了。
那么,怎么知道要左移多少次呢?从这里例子中看,
111每次计算后,向右移动一次,
101也跟着向左移动一次,直到
111只剩最后一位,则停止计算就好了。
代码实现
根据上面的思路,来实现一下代码:
// 用位运算实现加法 public static int add(int a, int b) { int sum = 0; while (b != 0) { sum = a ^ b; b = (a & b) << 1; a = sum; } return sum; } // 用位运算实现减法 public static int multi(int a, int b) { int res = 0; while (b != 0) { if ((b & 1) != 0) { res = add(res, a); } a <<= 1; b >>>= 1; } return res; }
运行一下代码,看下结果:
可以看到计算是正确的,而且还支持负数。