1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 使用移位运算和加减法实现乘除法

使用移位运算和加减法实现乘除法

时间:2022-03-10 18:26:53

相关推荐

使用移位运算和加减法实现乘除法

这个想法是在做leetcode 的题目29Divide Two Integers时产生的,原题描述如下:

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

就是说不用乘除取余运算来实现两个int醒变量的整除,然后如果溢出的话就返回INT_MAX。

先把问题简化一下,不考虑溢出问题,并且假设被除数n大于除数m大于0,嗯,基于这个假设,剩下的就是纯粹的算法部分了。说到整除问题,有n/m==k+r(r==n mod m),也就是我们小学学过的被除数除以除数等于商加余数。根据这个公式很自然的想到用n逐次减去m直到差小于m,代码如下;

int i=0;while (n>=m){n-=m;i++;}return i;

如果n和m比较接近的话,这样做还是很快的,但是对于一般情况,其时间复杂度为O(n/m),有些捉急,尤其是n特别大而m又很小的时候,简直不能忍,按这种思路提交的算法会提示超时(意料之中)。那么有没有别的方法呢?显然有!答案就是位运算。

使用左移和右移可以很方便地实现乘除2^的n次方,而 n/m==k+r 即 m*k==n-r 即 m*(2^l1+2^l2+……+2^ls)==n-r ,即m<<l1+m<,l2+……+m<<ls==n-r,于是整除运算就转化为移位运算和加减运算。然后可以写出如下代码:

int k=0,i=o;while (n>=m){if (n>=m<<i){k+=1<<i;n-=m<<i;++i;}else{i--;}}return k;

这样一来,一般情况下的时间复杂度大大降低,只有O(k的二进制表示的位数)。

同理,整数乘法也可以用位运算来实现。

int i=0,k=0;while (m){if (m>=1<<i){k+=n<<i;m-=1<<i;i++;}else{i=0;}}

以上就是我能想到的方法,然后具体到这个题目的话,还要考虑除数为0以及溢出问题,比如被除数为-2^31时该怎么解决。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。