位运算实现乘法运算
在回答本問題之前,先學習一些有關位運算的知識。
(1) 常用的等式: -n=~(n-1)=~n+1
(2) 獲取整數n的二進制中最后一個1: n&~(n-1)或者n&(-n)。例如n=010100,則-n=101100,n&(-n)=000100。
(3) 去掉整數n的二進制中最后一個1: n&(n-1)。例如n=010100,n-1=010011,則n&(n-1)=010000。
注:對n為正數或者負數都適用。
先看一個實例:1011*1010,因為二進制運算的特殊性,可以將該乘法運算表達式拆分成兩個運算,1011*0010于1011*1000的和。而對于二進制運算,左移一位,等價于乘以0010,左移三位,等價于乘以1000,所以兩者的乘積為10110于1011000的和,即為1101110.
因而乘法可以通過一系列的移位和加法運算完成。最后一個1通過n&~(n-1)求得,可通過n&(n-1)去掉最后一個1,為了高效的得到左移的位數,可提前計算一個map。算法如下,所示:
#include <iostream> #include <map> #include <exception> using namespace std; int multiply(int a,int b){bool neg=(b<0);if(b<0)b=-b;int sum=0;map<int,int> bits;for(int i=0;i<31;i++){bits.insert(pair<int,int>(1<<i,i));}while(b>0){//循環條件int bitshift=bits[b&~(b-1)];//獲取移位的次數sum+=a<<bitshift;b&=b-1;//去掉最后的1}if(neg)sum=-sum;return sum; } int main() {cout<<multiply(3,-5)<<endl;return 0; }
總結
- 上一篇: ubuntu下网易云音乐适配高分辨率屏幕
- 下一篇: 潜伏在大厂中“摸鱼”的打工人