每天一道LeetCode----位运算实现加减乘除四则运算

Divide Two Integers

原题链接Divide Two Integers
这里写图片描述
意思是重新实现除法运算,这里不要复习一下用位运算实现加减乘除四则运算
C++学习笔记—–用位运算实现加减乘除以前也有记录过,这里主要是复习,另外,除法需要优化,在这里实现


加法

通过异或运算和与运算实现
两个二进制数相加,异或运算的结果是不考虑进位时的结果
两个二进制数相加,与运算的结果是对应为是否有进位

0101 + 0001 = 01100101 ^ 0001 = 0100
0101 & 0001 = 0001
异或结果表明,如果不考虑进位,那么结果为0100
与运算结果表明,最低位需要向次低位进1算式改为0100 + 00010(与结果左移一位,将进位加到高位上)
计算结果0101

代码实现

int add(int a, int b)
{return b == 0 ? a : add(a ^ b, (a & b) << 1);
}

减法

同加法,减去一个数等于加一个数的相反数

int negative(int n)
{return add(~n, 1);
}int sub(int a, int b)
{return add(a, negative(b));
}

乘法

笔算二进制乘法

        0101    a×   0110    b----------------
        000001010101+ 0000-------------
     00011110

b的每一位乘a,左移一定位数后加到结果上,代码把逻辑实现出来就可以了。可以在代码中每加一次结果就将a左移一位,就不需要每次算完都左移。最好考虑符号问题,乘之前都转为正数

int get_sign(int n)
{if(n >> 31)return 1;elsereturn 0;
}int positive(int n)
{if(n >> 31)return negative(n);elsereturn n;
}int multi(int a, int b)
{bool be_negative = false;if(get_sign(a) ^ get_sign(b))be_negative = true;unsigned int x = positive(a);unsigned int y = positive(b);int n = 0;while(y | 0){if(y & 1)n = add(n, x);x = x << 1;y = y >> 1;}return be_negative ? negative(n) : n;
}

除法

第一种方法,每次循环都是a-b,看能减多少次,如果a很大b很小,效率比较低
第二种方法,从最大倍数n开始,看看a / n 是否大于b,如果大,将n加到结果上,然后缩小倍数继续循环

int div(int a, int b)
{bool be_negative = false;if(get_sign(a) ^ get_sign(b))be_negative = true;unsigned int x = positive(a);unsigned int y = positive(b);int res = 0;int i = 31;while(i >= 0){if((x >> i) >= y){res = add(res, 1 << i);x = sub(x, y << i);}/* 也可以在else里,因为这里是int型,最大也就1 << 31*/i = sub(i, 1);}/* 题中要求溢出时为INT_MAX,实现时可以让它溢出 *///if(res < 0 && !be_negative)//    return INT_MAX;return be_negative ? negative(res) : res;}

完整测试程序如下

#include 
#include 
#include using namespace std;class Solution {
public:int add(int a, int b){return b == 0 ? a : add(a ^ b, (a & b) << 1);}int sub(int a, int b){return add(a, negative(b));}int get_sign(int n){if(n >> 31)return 1;elsereturn 0;}int negative(int n){return add(~n, 1);}int positive(int n){if(n >> 31)return negative(n);elsereturn n;}int multi(int a, int b){bool be_negative = false;if(get_sign(a) ^ get_sign(b))be_negative = true;unsigned int x = positive(a);unsigned int y = positive(b);int n = 0;while(y | 0){if(y & 1)n = add(n, x);x = x << 1;y = y >> 1;}return be_negative ? negative(n) : n;}int div(int a, int b){bool be_negative = false;if(get_sign(a) ^ get_sign(b))be_negative = true;unsigned int x = positive(a);unsigned int y = positive(b);int res = 0;int i = 31;while(i >= 0){if((x >> i) >= y){res = add(res, 1 << i);x = sub(x, y << i);}i = sub(i, 1);}//if(res < 0 && !be_negative)//    return INT_MAX;return be_negative ? negative(res) : res;}
};int main()
{Solution s;srand(unsigned(time(NULL)));int maxIteration = 10000;while(maxIteration--){int a = rand() - INT_MAX / 2;int b = rand() - INT_MAX / 2;if(s.add(a, b) != a + b)cout << "error : " << a << " + " << b << endl;if(s.sub(a, b) != a - b)cout << "error : " << a << " - " << b << endl;if(s.multi(a, b) != a * b)cout << "error : " << a << " * " << b << " " << s.multi(a, b) << " " << a * b << endl;if(b != 0 && s.div(a, b) != a / b)cout << "error : " << a << " / " << b << endl;}return 0;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部