每天一道LeetCode----位运算实现加减乘除四则运算
来源:互联网 发布:网络电影漂亮女主角 编辑:程序博客网 时间:2024/06/05 05:57
Divide Two Integers
原题链接Divide Two Integers
意思是重新实现除法运算,这里不要复习一下用位运算实现加减乘除四则运算
C++学习笔记—–用位运算实现加减乘除以前也有记录过,这里主要是复习,另外,除法需要优化,在这里实现
加法
通过异或运算和与运算实现
两个二进制数相加,异或运算的结果是不考虑进位时的结果
两个二进制数相加,与运算的结果是对应为是否有进位
0101 + 0001 = 01100101 ^ 0001 = 01000101 & 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 ---------------- 0000 0101 0101 + 0000 ------------- 00011110
b的每一位乘a,左移一定位数后加到结果上,代码把逻辑实现出来就可以了。可以在代码中每加一次结果就将a左移一位,就不需要每次算完都左移。最好考虑符号问题,乘之前都转为正数
int get_sign(int n){ if(n >> 31) return 1; else return 0;}int positive(int n){ if(n >> 31) return negative(n); else return 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 <iostream>#include <climits>#include <random>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; else return 0; } int negative(int n) { return add(~n, 1); } int positive(int n) { if(n >> 31) return negative(n); else return 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;}
阅读全文
0 0
- 每天一道LeetCode----位运算实现加减乘除四则运算
- 位运算实现加减乘除四则运算
- 用位运算实现四则运算之加减乘除 .
- 用位运算实现四则运算之加减乘除
- 用位运算实现四则运算之加减乘除
- 用位运算实现四则运算之加减乘除
- 使用位运算实现加减乘除四则运算
- 用位运算实现四则运算之加减乘除
- 用位运算实现四则运算之加减乘除
- 用位运算实现四则运算之加减乘除
- 用位运算实现四则运算之加减乘除
- 使用“位运算”实现“四则运算”之加减乘除
- 用位运算实现四则运算之加减乘除
- 用Java位运算实现加减乘除四则运算
- 只用位运算来实现整数的加减乘除四则运算
- 只用位运算来实现整数的加减乘除四则运算
- 位操作实现加减乘除四则运算
- 位操作实现加减乘除四则运算
- 3W纷享派 | 以书会友:与你共同深刻解读《增长黑客》
- 一个完美的逗号——赛创周年庆
- 优步与滴滴血战进入白热化 谁能决胜紫禁之巅?
- 中科院丁汉:制造技术的限制是先进技术无法实用化的重要原因
- 分享一波Unity3D CSharp 对车的第三人称视角摄像机脚本
- 每天一道LeetCode----位运算实现加减乘除四则运算
- RESTful Web Service 架构剖析
- glFlush()和glFinish()glutSwapBuffers()区别
- 有关platform tools的安装不成功问题
- Javascript原型Prototype理解
- 项目中使用svg格式的字符串转换图片并把图片插入到word和pdf文档
- HDU
- 原ABB首席科学家甘中学:我们要做"心灵手巧" 的工业机器人
- 北理孔祥战:服务机器人这个品类在消费者脑子里还没有 | 中国机器人峰会