[转]C++二进制完成加减乘除

 

首先介绍计算机的二进制码

二进制常用的有原码,反码和补码,他们都是由最左边的一个符号位和右边的数值位构成。在计算机中为了更低成本的计算,数据都是用补码来存储和运算的。

原码

最高位表示符号位(0代表正数,1代表负数)。剩下的位数,是这个数的绝对值的二进制。

比如 一个int变量大小为4字节,在32位的编译器中的二进制表示就是00000000 00000000 00000000 00000000
那么10 的原码就是00000000 00000000 00000000 00001010
−10的原码就是 10000000 00000000 00000000 00001010

反码

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

10的反码就是00000000 00000000 00000000 00001010 和原码一样
−10的反码就是11111111 11111111 11111111 11110101

补码

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

10的补码就是00000000 00000000 00000000 00001010
−10的补码就是 11111111 11111111 11111111 11111011

总结一下

计算机系统中,数值一律用补码来表示:因为补码可以使符号位和数值位统一处理,同时可以使减法按照加法来处理。
二进制编码:数值编码分为原码,反码,补码,符号位均为0正1负。

原码 -> 补码: 数值位取反加1

补码 -> 原码: 对该补码的数值位继续 取反加1

补码 的绝对值(称为真值):正数的真值就是本身,负数的真值是各位(包括符号位)取反加1(即变成原码并把符号位取反).

介绍基本的位操作

^:按位异或;&:按位与; | :按位或
b -> -b : 各位(包括符号位)取反加1

用位操作实现加法运算

我们先不考虑进位,在1位数的加法上,如下
1. 1+1=0
2. 1+0=1
3. 0+1=1
4. 0+0=0
很明显上面几个表达式我们可以用异或进行统一
1. 1^1=0
2. 1^0=1
3. 0^1=1
4. 0^0=0
这样我们就完成了最基础的一位数的加法,但是怎么计算二位以上的加法呢?我们发现现在方法的问题在于不能够获取进位,于是我们通过观察一位数的加法的式子,发现只有两个数位都是1的时候才会有进位,其他都不进位,这不是和&很像吗? 我们通过把+换成&得到下式
1. 1&1=0 不进位
2. 1&0=1 不进位
3. 0&1=1 不进位
4. 0&0=0 进位
那么我们把所有位进行&操作,然后<<左移一位,不就可以当作加数当前的进位吗?
到这里我们就完整解决了二进制相加问题中,对应位的相加和进位的问题
1. x^y 加法
2. (x&y)<<1 进位操作
那么总结一下:

定理1:设a,b为两个二进制数,则a+b=a^b+(a&b)<<1。
证明:

a^b是不考虑进位时加法结果。当二进制位同时为1时,才有进位,因此 (a&b)<<1是进位产生的值,称为进位补偿。将两者相加便是完整加法结果。

定理2:使用定理1可以实现只用位运算进行加法运算。
证明:

利用定理1中的等式不停对自身进行迭代。每迭代一次,进位补偿右边就多一位0,因此最多需要加数二进制位长度次迭代,进位补偿就变为0,这时运算结束。

那么我们可以根据上面的定理得到实际的C++代码如下

int add(int a, int b){int re = a;while(b){int tmp = a;a = a^b;b = (tmp&b)<<1;re = a;}return re;
}

用位操作实现减法

减法和加法原理相同,减去一个数相当于加上这个数的相反数,所以完全可以利用加法操作,唯一需要做的就是求出被减数的相反数。
求相反数的方法:每一位取反,末位加一。
代码如下:

int subtraction(int a, int b)
{b = add(~b,1); // 求b的相反数return add(a, b);
}

用位操作实现乘法

二进制的乘法同十进制的乘法并无什么不一样,对于a∗b每次只需要将a左移对应的位,然后同上一次的结果相加即可
当b的对应位为1的时候,对a左移一位相加即可
当b的对应位位0的时候,对a左移一位,但是不相加
注意到我们上面的操作都是不包括符号位的,因此我们单独考虑符号位。
代码如下

int getSign(int n)
{unsigned count = 0;//计算n的位数do{++count;}while(n >> count)//得到n的最左边的位return n >> (count-1);
}int mul(int a, int b){bool isNegative = false;if(getSign(a) ^ getSigned(b))isNegative = true;if(a < 0) a = add(~a,1);//求出a的绝对值if(b < 0) b = add(~b,1);//求出b的绝对值int res = 0;while(b){               //当b不为0,继续循环if(b & 1)           //当b当前位为1 才需要加ares = add(res,a);a = a << 1;b = b >> 1;}if(isNegative)add(~res,1);return res;
}

二进制除法

同乘法一样,除法一样可以用减法来代替,当a≥b才可以上商,在每次上一个商(也就是商值加1)之后,a=a−b
代码如下

int divide(int a, int b){if(!b)throw std::runtime_error("Divided can't be zero...");bool isNegative = false;bool isNegtive = false;if(getSign(a) ^ getSign(b))isNegtive = true;if(a < 0) a = add(~a,1);//求出a的绝对值if(b < 0) b = add(~b,1);//求出b的绝对值int res = 0;while(a >= b){res = add(res,1);a = subtraction(a,b);}if(isNegative)add(~res,1);return res;
}


---------------------
作者:harry_128
来源:CSDN
原文:https://blog.csdn.net/harry_128/article/details/80150502
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

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

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

相关文章

WGS84(GPS)、火星坐标系(GCJ02)、百度地图(BD09)坐标系转换案例教程(附转换工具下载)

在做基于百度地图、高德地图等电子地图做为地图服务的二次开发时,通常需要将具有WGS84等坐标的矢量数据(如行政区划、地名、河流、道路等GIS地理空间数据)添加到地图上面,然而,在线地图大多使用的是火星坐标系,需要事先将矢量数据转为火星坐标系。本文以案例的形式,讲述…

.NET 6 AssemblyLoadContext DLL 库 热插拔逻辑实现

曾经也实现过.Net Framework 基于AppDomain 的 dll库热插拔&#xff0c;经历了版本的迭代&#xff0c;.Net Core 不支持 AppDomain&#xff0c;之前也搞过.Net Core 3.1 版本的&#xff0c;现在搞一下子.NET 6.0的。热插拔运用的场景主要运用到宿主与插件这个场景或者动态任务的…

C语言试题193之实现strcmp函数功能

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目: 实现st…

浅谈Java多线程同步机制之同步块(方法)——synchronized

在多线程访问的时候&#xff0c;同一时刻只能有一个线程能够用 synchronized 修饰的方法或者代码块&#xff0c;解决了资源共享。下面代码示意三个窗口购5张火车票&#xff1a; 1 package com.jikexueyuan.thread;2 /*3 * 未使用synchronized&#xff0c;存在并发4 */5 class…

[转]Webpack5(从入门到精通)

这里写目录标题 1、webpack 初体验 全局安装webpack2.打包样式资源 创建webpack.config.js文件&#xff08;配置文件&#xff09;3.打包html资源 webpack.config.js文件&#xff08;配置文件&#xff09;4.打包图片资源 webpack.config.js文件&#xff08;配置文件&#xff09;…

mybatis由浅入深day01_5mybatis开发dao的方法(5.1SqlSession使用范围_5.2原始dao开发方法)...

5 mybatis开发dao的方法 5.1 SqlSession使用范围 5.1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory 将SqlSessionFactoryBuilder当成一个工具类使用即可&#xff0c;不需要使用单例管理SqlSessionFactoryBuilder。 在需要创建SqlSes…

做⼀个⾼德地图的 iOS / Android MAUI 控件(上)

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;10分钟)Microsoft Build 2022 ⼤会上正式发布了 .NET MAUI , 对于 .NET 开发者可以⽤ C# 完成跨平台的前端应⽤开发。对⽐起 MAUI 的前身 Xamarin , MAUI 除了可以⽤传统的原⽣开发模式外&#xff0c;还⽀持了 Blazor…

易康eCognition Developer 9.01安装教程(附eCognition下载地址及中文教程)

eCognition是由德国Definiens Imaging公司2009年推出的智能化影像分析软件,2010年被美国Trimble公司收购。eCognition是目前所有商用遥感软件中第一个基于目标信息的遥感信息提取软件,它采用决策专家系统支持的模糊分类算法,突破了传统商业遥感软件单纯基于光谱信息进行影像…

[改善Java代码]不要覆写静态方法

建议33&#xff1a; 不要覆写静态方法 我们知道在Java中可以通过覆写&#xff08;Override&#xff09;来增强或减弱父类的方法和行为&#xff0c;但覆写是针对非静态方法&#xff08;也叫做实例方法&#xff0c;只有生成实例才能调用的方法&#xff09;的&#xff0c;不能针对…

C语言试题194之实现strcpy函数功能

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目: 实现st…

ArcGIS实验教程——实验四十三:ArcGIS栅格重分类(Reclass)案例详解

文章目录 一、重分类1. 新值替代2. 将值组合到一起3. 按相同等级对一组栅格的值进行重分类4. 将特定值设置为NoData 或者为 NoData像元设置某个值二、查找表三、分割四、使用表重分类五、使用ASCI文件重分类重分类就是对原有栅格像元值重新分类从而得到一组新值并输出。重分类工…

[中文版] 可视化 CSS References 文档

本文分享了我将可视化 CSS References 文档翻译成中文版的介绍&#xff0c;翻译工作还在陆续进行中&#xff0c;供学习 CSS 参考。 1. 可视化 CSS References 文档介绍 许多 CSS 的文档都是属性的介绍&#xff0c;而开源项目 css-reference 并没有提供中文版&#xff0c;而当我…

对比 C# 聊聊 C++ 中几类特殊成员函数

一&#xff1a;背景 在 C# 中要说类默认给我们定义的特殊成员函数&#xff0c;莫过于 构造函数&#xff0c;但在 C 中这样的特殊函数高达 6 种&#xff0c;有必要整合一下聊一聊。二&#xff1a;特殊成员函数 1. 默认构造函数和 C# 一样&#xff0c;很多书中都说&#xff0c;如…

Js 枚举定义Layer Icon

layer的icon有7种样式&#xff1a;1-7 [图片来自&#xff1a;https://blog.csdn.net/beauxie/article/details/60959971] 有时候常常记不住 &#x1f623;&#xff0c;不防自己定义一哈&#xff1a; var layerIcon {//无none: -1,//成功success: 1,//失败error: 2,//提问、疑…

前端进阶之路: 前端架构设计(2)-流程核心

可能很多人和我一样, 首次听到"前端架构"这个词, 第一反应是: "前端还有架构这一说呢?" 在后端开发领域, 系统规划和可扩展性非常关键, 因此架构师备受重视, 早在开发工作启动之前, 他们就被邀请加入到项目中, 而且他们会跟客户讨论即将建成的平台的架构要…

C语言试题195之实现strnchr函数功能

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目: 实现strnchr函数功能 函数名称:在字符串中查找字符 函数原型:char *strnchr(cons…

8.2设备文件及磁盘分区

2019独角兽企业重金招聘Python工程师标准>>> 概览&#xff1a; 设备文件的创建 权限 设备名 类型 主设备号 次设备号 mknod [-m MODE] NAME type [MAJOR MINOR] 创建时&#xff0c;先查看是否存在设备号的冲突 零磁道零扇区是MBR&#xff1a;Maste…

【ArcGIS风暴】ArcGIS求一个矢量图层中多个图斑的“四至点”坐标案例教程

如图所示,为ArcGIS软件自带的全球矢量数据,怎样求取每个大洲(图斑)的四至坐标(xmin、ymin、xmax、ymax)呢? 参考阅读:【ArcGIS遇上Python】python批量获取栅格数据四至(top,bottom,left,right)坐标代码 文章目录 1. 矢量数据加载2. 四至计算结果3. 四至计算过程1.…

一个关于导出excel模板的实例

1 首先jsp页面 点击模板下载&#xff0c;会自动下载模板&#xff45;&#xff58;&#xff43;&#xff45;&#xff4c;&#xff0c;效果如下 让我们看源码&#xff1a; &#xff11; &#xff4a;&#xff53;&#xff50;页面 <div class"tab-pane" id"p…

腾讯视频VIP会员,周卡特价9.5元!

今天给大家推荐特价充值腾讯视频VIP会员的平台——幻海优品&#xff0c;腾讯视频在线直充&#xff0c;VIP会员实时生效&#xff01;腾讯视频VIP会员特价充值周卡&#xff1a;原价12元&#xff0c;特价9.5元月卡&#xff1a;原价30元&#xff0c;特价22元季卡&#xff1a;原价68…