位运算实现四则运算(C++实现)

前言

Leetcode中有一道这样的题:给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。返回被除数 dividend 除以除数 divisor 得到的商。
如果正常的四则运算符号不允许使用,呢这道题的考点我觉得应该是位运算来实现,遇到了就好好复习一下,下面将介绍二进制实现四则运算:

二进制码

位运算是基于二进制运算的,实际上目前的计算机都只识别二进制码,我们所写的一切指令事实上都是一串010101数字、传输数据也是按比特流的形式传输的。所以先介绍二进制码:

原码

最高位表示符号位(0代表正数,1代表负数)。剩下的位数,是这个数的绝对值的二进制。
比如 一个int变量大小为4字节,在32位的编译器中的二进制表示就是00000000 00000000 00000000 0000000

10 的原码  00000000 00000000 00000000 00001010
−10的原码 10000000 00000000 00000000 00001010

反码

正数的反码和其原码是一样的
负数的反码就是在其原码的基础上 符号位不变 其他位取反。

10的反码:  00000000 00000000 00000000 00001010
−10的反码:11111111  11111111 11111111 11110101

补码

正数的补码就是其原码
负数的补码就是在其反码的基础上+1

10的补码:00000000 00000000 0000000 00001010 
−10的补码:11111111 11111111 11111111 11110110

在计算机系统中,数值一律用补码来表示:因为补码可以是符号位和数值位统一处理,同时可以试减法按照加法来处理。

位运算加法

0111 ^ 0101 = 0010; //结果的每一位等于对应位相加模二,刚好是不带进位的加法结果。
0111 & 0101 = 0101; //结果的1表示对应位相加为2,0表示对应位相加小于二,刚好是进位标识。

所以有:

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

位运算减法

减法其实就是加上这个数的相反数,这个数原来是用正数的补码表示的,现在变成负数的补码形式了:所以只需要将这个数每一位取反再末尾家一就行了:

int subtraction(int a, int b)
{b = add(~b, 1);return add(a, b);
}

位运算乘法

对于a * b,每次只需要将a左移一位乘上b的对应位,然后同上一次的结果做加法即可。
当b的对应位为1时,对a左移一位然后同上一次的结果做加法;如果b的对应位为0,只对a左移一位。

int getsign(int n)
{return n >> 31;
}int positive(int n)
{return (getsign(n) & 1) ? add(~n,1): n;
}int multiply(int a, int b)
{bool flag = (getsign(a) ^ getsign(b)) ? 1 : 0;a = positive(a);b = positive(b);int res = 0;while (b) {if (b & 1)res = add(res, a);   //只有当前b末尾为1时才运算a = a << 1;  b = b >> 1;}if (flag)add(~res, 1);return res;
}

位运算除法

同乘法一样,除法也可以进行二进制笔算,以a / b为例,只有当a >= b时才可以上商,又因为是二进制,所以商每次只会多1,在每次上1之后a都要减去一次b。

int divide(int a, int b)
{if (b == 0)throw runtime_error("DIVIDED CANNOT BE 0");bool flag = (getsign(a) ^ getsign(b)) ? 1 : 0;a = positive(a);b = positive(b);int res = 0;while (a >= b){res = add(res, 1);a = subtraction(a, b);}return flag ? add(~res, 1) : res;
}

总代码如下:

int add(int a, int b)
{return (b == 0) ? a : add(a^b, (a&b) << 1);
}int subtraction(int a, int b)
{b = add(~b, 1);return add(a, b);
}int getsign(int n)
{return n >> 31;
}int positive(int n)
{return (getsign(n) & 1) ? add(~n,1): n;
}int multiply(int a, int b)
{bool flag = (getsign(a) ^ getsign(b)) ? 1 : 0;a = positive(a);b = positive(b);int res = 0;while (b) {if (b & 1)res = add(res, a);   //只有当前b末尾为1时才运算a = a << 1;  b = b >> 1;}if (flag)add(~res, 1);return res;
}int divide(int a, int b)
{if (b == 0)throw runtime_error("DIVIDED CANNOT BE 0");bool flag = (getsign(a) ^ getsign(b)) ? 1 : 0;a = positive(a);b = positive(b);int res = 0;while (a >= b){res = add(res, 1);a = subtraction(a, b);}return flag ? add(~res, 1) : res;
}

转载于:https://www.cnblogs.com/yunlambert/p/9845897.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464573.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用croc命令在Linux系统电脑之间传输文件和文件夹

‍在两台或多台计算机之间传输文件的方法有很多。‍你可以使用基于服务器的文件共享工具&#xff0c;点对点文件共享app&#xff0c;U盘&#xff0c;外部硬盘驱动器&#xff0c;SCP&#xff0c;NFS&#xff0c;FTP&#xff0c;HTTP&#xff0c;云存储平台等等。本文将介绍一个名…

Lady Bird

La Ballade of Lady Bird[Lady Bird]Bird : Lady? Lady : Yes Bird? Bird : Its cold Lady : I know Lady : Bird... I cannot see a thing Bird : Its all in your mind Lady : Im worried Bird : No one will come to see us Lady : Maybe they come but we just dont see …

redhat oracle 开机自启动

一&#xff1a;修改 /etc/oratab N 改为Y 二&#xff1a;修改dbstart dbshut su - oracle cd $ORACLE_HOME/bin vi dbstart 找到 ORACLE_HOME_LISTNER/ade/vikrkuma_new/oracle ###########9i下没有&#xff0c;不用修改 改为 ORACLE_HOME_LISTNER$ORACLE_HOME 同样道理修改d…

Android中的5种数据存储方式

Android中的5种数据存储方式 Android中的5种数据存储方式 数据存储在开发中是使用最频繁的&#xff0c;在这里主要介绍Android平台中实现数据存储的5种方式&#xff0c;分别是&#xff1a; 1 使用SharedPreferences存储数据&#xff1b; 2 文件存储数据&#xff1b; 3 SQLit…

揭秘 | 小米最新款12PRO智能动态刷新率技术原理

1. 背景最新发布的小米手机12pro提到了一个安卓系统上的新技术&#xff1a;智能动态刷新率。这到底是个啥技术&#xff1f;让雷军同学可以大吹特吹。智能动态刷新海报要解释上面的技术&#xff0c;不得不提刷新率和帧率这两个概念。在平时的生活当中&#xff0c;你可能也会经常…

java怎么编程方程_[编程入门]自定义函数求一元二次方程-题解(Java代码)

令一元二次方程判别式&#xff1a; b2 - 4ac为变量P**当P > 0时&#xff1a;**x1 (-bsqrt(P)) / 2ax1 (-b-sqrt(P)) / 2a**当P 0时&#xff1a;**x1 x2 -b / 2a**当P < 0时&#xff0c;一元二次方程无解当存在共轭复数&#xff1a;**x1 -b/2a sqrt(-P)ix1 -b/2a …

自动部署war包脚本

war 包所在路径为&#xff1a;/home/wars/ROOT.war tomcat 所在路径为&#xff1a; ①&#xff1a;/home/search-3 ②&#xff1a;/home/search-4 部署单个war到一个tomcat中 #!/bin/sh TOMCAT/home/search-3 echo "deploy ROOT.war"#ps 显示进程,grep筛选进程,awk是…

吉他谱——有多少爱可以重来

C C Am Am C C 常常责怪自 己 当初不 应 该&#xff0c;   常常后悔没 有 把你留 谁知道又和 你 相遇在 人 海&#xff0c;   命运如此安 排 总教人 Am Am Dm G C Am 下 来。 为甚 么 明明相 爱&#xff0c; 到最 后 还是要 分开&#xff0c; 是否 无 奈…

如何在Ubuntu 11.10下安装Java

升级到ubuntu 11.10之后&#xff0c;由于库里没有sun-java6-jdk&#xff0c;需要自行安装。因此&#xff0c;到Oracle网站下载了Java 6u27&#xff08;为什么不下java7呢&#xff1f;因为目前支持的软件不多&#xff0c;另外如果真要的话&#xff0c;也可以很方便的切换到Java7…

看看高手做的ARM开发板

放假前&#xff0c;我写了一篇文章&#xff0c;里面有提到我放假的时候会接触一个开发板&#xff0c;这个开发板就是标题提到的这个ARM处理器&#xff0c;这篇文章会对这个处理器和开发板做个简单的介绍。说这个开发板前&#xff0c;先介绍下我的一个朋友zzy。zzy是通过公众号接…

Flow monitoring in Software-Defined Networks

题目&#xff1a;Flow monitoring in Software-Defined Networks: Finding the accuracy/performance tradeoffs 软件定义网络中的流量监控&#xff1a;寻找准确性/性能权衡 发表时间&#xff1a;2018年 来源&#xff1a;Computer Networks (Elsevier) 摘要 在基于OpenFlow的软…

java给腾讯通发消息_通过web 向rtx发送通知消息

请通过调用RTX服务器CGI的方式实现&#xff0c;详细说明如下&#xff1a;发送消息提醒方法&#xff1a;GET/POSTURL:/sendnotify.cgi用法举例(IE地址栏中输入)&#xff1a;http://192.168.17.221:8012/sendnotify.cgi?msghello&receiverwwjs参数表&#xff1a;变量名称 默…

心情-天气

最近雨还满多的&#xff0c;但不是阴雨连绵&#xff0c;中间会时不时有个大晴天。一直觉得下雨的日子就应该是安排在周一到周五&#xff0c;这样的话我就可以安心的聚精会神的上班&#xff0c;因为反正下雨哪里也不想去&#xff0c;还是好好上班比较好&#xff0c;躲在办公室里…

用 Shell 快速写一个嵌入式测试框架

大家好&#xff0c;转发我朋友老吴的一篇文章&#xff0c;我们在做测试框架的时候用的是python&#xff0c;但是一些理论基础和用shell是一样的&#xff0c;在这里&#xff0c;语言并不是关键。希望对大家有帮助。哈喽&#xff0c;我是老吴。作为一个嵌入式底层码农&#xff0c…

不同技术团队的配合问题及DevOps

一、技术团队细分及配合问题 在IT企业里产品从创意到交付给用户&#xff0c;从整体上看是由技术部门负责&#xff0c;但如果深入到技术部门&#xff0c;会发现由不同的技术团队负责不同的部分或者阶段。一般会 分产品团队、开发团队、测试团队以及运维团队&#xff0c;在互联网…

jquery validation验证身份证号、护照、电话号码、email

$.validator.setDefaults({ submitHandler: function(form) { form.submit(); } }); // 字符验证 jQuery.validator.addMethod("stringCheck", function(value, element) { return this.optional(element) || /^[\u0391-\uFFE5\w]$/.test(value); }, "只能包括中…

C++/C中定义与声明的区别

在C/C中&#xff0c;定义与声明是不一样的&#xff0c;主要区别在于是否分配了内存。 定义&#xff1a;编译器创建一个对象&#xff0c;为该对象分配一块内存&#xff0c;并为该内存起一个名字&#xff0c;这个名字就叫变量名。 例如&#xff1a; int a;//未初始化 int b 0;…

ubuntu php.ini 配置,ubuntu下配置PHP+JSON模块(apache) | 学步园

搭配完毕apachephpmysql环境后我们开始来配置PHP加载JSON模块1.下载源文件包&#xff1a;wget http://www.aurore.net/projects/php-json/php-json-ext-1.2.0.tar.bz22.解压tar xvjf php-json-ext-1.2.0.tar.bz23.进入目录cd php-json-ext-1.2.04.编译前要初始化PHP环境:phpiz…

A good book to learn C#2.0 ----C# 2.0 : Practical Guide for Programmers

c#2.0,已经出来很久了,相信已经有不少人或多或少了解了它的一些特性了.而这本<C# 2.0 : Practical Guide for Programmers>(作者&#xff1a;Michel de Champlain, Brian G. Patrick)是一本2005年2月出的turorial类型的好书,通过这本书不仅可以学习c#2.0的新内容,还可以对…

单线程会导致死锁吗?

我之前在我们的项目里面解决了一个死锁的问题&#xff0c;然后我跟一个我的朋友聊了下&#xff0c;他让我深入研究下这个问题。大家也可以考虑想我的这个问题。首先我们再看看什么是死锁&#xff1f;什么是死锁用个通俗的例子讲一讲死锁死锁从文字理论上说明的是两个线程&#…