二进制补码:Why & How
二进制补码:Why & How
学习计算机原理或者语言的底层操作难免会遇到用二进制补码表示负数的问题。由于一些书本上对于采用补码的原因没有详细解释,很多人会认为这只是一种规定,但实际上采用补码是因为这种表示方法拥有实际的优势。而对于求补码的方法“按位取反再加一”,给出解释的资料就更少,本文试图给出二进制补码的优势和求法的简单解释。
Why
首先回答为什么要使用补码的问题。补码是一种计算机中负数的表示方法,当然,计算机中可以表示负数的方法不止补码一种,但目前几乎只有补码这种方法得到了广泛运用。数字的表示方法影响到数字在计算机中的存储和运算,下面对比三种可行的负数表示法来说明补码在这两方面的优势。
带符号的原码
最容易想到的负数表示方法就是将一个二进制位用来表示数的符号,例如规定数字的最高位是0时为正数,是1时为负数,把这一最高位加在负数绝对值的二进制表示(也即原码)的前面。这种方法非常直观易懂,例如310可以被表示为00112而-310可以表示为10112。我们平时在进行整数运算时可以把符号当作减号,但计算机执行简单的加法时并不会这样处理,以-310+310为例,计算机将00112+10112相加后得到11102=610从而产生了完全错误的结果。当然通过额外的电路或者程序可以让计算机像我们一样处理负号,但这会增加电路成本或影响性能。
偏置数制
为了解决运算负数在计算机中的运算问题,可以让存储的二进制值表示它的值减去某个数得到的数字。例如,对于三位二进制数,规定计算机存储的二进制数a实际上表示的是a-4对应的数字。这样0002不再表示010而是-410,而1002才表示010。这样的三位二进制数可以表示[-4, 3]范围内的所有整数,而由于并不存在需要额外处理的符号位,直接对偏置数制表示的二进制数进行加法得到的结果总是正确的。这种表示法的问题在于,要想得到存储的二进制数原来表示的数字,总要将其再加上某个数值——虽然稍显麻烦,但这已经比带符号原码在每次运算时都要处理符号要进了一大步。
补码
补码是一种兼具上面两种表示法特点和优势的数制。补码同样使用二进制数的最高位来表示符号,并规定最高位为1时表示负数。不同于带符号的原码的是,当表示负数时,补码采用偏置数制。例如,表示-410时,首先将-410+810得到偏置数1002,然后在前面加上符号位1得到11002,即是-4的四位二进制补码;正数的表示方法则与带符号的原码完全相同。注意这里所说的偏置数制与上述的略有不同,这里的二进制表示和实际数值差8而不是4,这是因为我们想利用低三位表示[-8,-1]范围的数。补码的正数和负数加法都很好理解,因为正数加正数或负数加负数并不涉及符号位的变化。而对于正数加负数,补码也能得到正确的结果,以-210+310为例,11102+00112=00012,注意到最高位因为来自低位的进位而由1变成了(1)0,最高位产生的进位溢出而被忽略,这样的溢出不会造成运算结果出错所以无需顾虑。补码表示法下的负数加上正数时,若正数大于等于负数的绝对值,将产生一个向最高位的进位而改变符号,从而保证了结果的正确性。你也许要为偏置数制争辩,尽管补码可以让正数容易得到,但负数却还是需要额外的运算。下面将展示这种计算可以是相对简单的。
How
至于如何从负数的原码得到补码,几乎所有的教科书都给出了“绝对值按位取反再加一”这一捷径,但关于其中道理能阐明的却很少。对最高位取反很容易理解,因为绝对值为正,需要变换符号才能表示负数,我们着重讨论低位的情况。以4位二进制补码为例,除最高位外的低3位实际上表示该负数a比-8大了多少(例如-210的补码11002的低三位1002=610表示-2比-8大6),也即:
a+8=a-(-8)
换句话说,这是求该负数的绝对值比8小了多少:
a-(-8)=8-(-a)=8-|a|
不过我们更希望能用710去减掉a的绝对值,因为710是01112,而01112去减掉任意一个[110, 710]内的数(也即[00012, 01112]内的数)的差正好是被减数的按位取反(对于每一位,1-0=1;1-1=0)。但记住,我们要求的值是与8的差,如果用7去减就要再加一补回来:
8-|a|=7-|a|+1
这就是按位取反再加一的原理,尽管我们是用4位二进制补码来演示的,对于更高位数也很容易想象到推广的情形。 值得一提的是,虽然上面的分析是从方便我们计算的角度考虑的,但实际上“按位取反再加一”是为了方便计算机计算而产生的技巧(取反和加一都是很容易实现的操作),也同时是补码相对于其他两种表示法的优越性所在。
二进制补码:Why & How的更多相关文章
- 利用ZYNQ SOC快速打开算法验证通路(1)——MATLAB浮点数与定点二进制补码互转
最近本人一直在学习ZYNQ SOC的使用,目的是应对科研需要,做出通用的算法验证平台.大概思想是:ZYNQ PS端负责与MATLAB等上位机数据分析与可视化软件交互:既可传输数据,也能通过上位机配置更 ...
- java基础 二进制补码
二进制补码: 1.计算机系统的内部以二进制形式存储数据. 2.在Java程序中输入的十进制的数据都会被自动转换为二进制,Java内部也以二进制来进行数值运算,但返回的结果是十进制. 二进制补码的原理: ...
- 二进制补码除法——计算机底层整数除法模拟之Java实现
前面讲到布思算法的计算机底层模拟的时候,我们是借助于一个可以储存.表示任意N位的二进制补码的BinaryQueue实现的,现在我们模拟计算机底层整数除法还是要借助于它: BinaryQueue类代码: ...
- Day05_C操作符及二进制补码计算
回顾: 1.数据类型 2.二进制(八进制,十六进制) --------------------------------------------------------- 计算机中不可以使用负号表示 ...
- 任意N位二进制的补码实现——队列存放
正在学习计算机组织与结构,为了写一些底层的算术操作模拟,比如一个二进制补码数的加减乘除,发现这很麻烦,因为不管是什么语言,都只提供了8位.32.64位等部分位数的补码形式,那么怎么实现任意任意位的补码 ...
- int abs(int number)函数有感: 求补码和通过补码求对应的整数 C++(增加:数字的二进制表示中1的个数)
#include "limits.h" #include "math.h" int abs(int number) { int const mask = num ...
- 二进制原码、反码、补码以及Java中的<< 和 >> 和 >>> 详细分析
1.计算机二进制系统中最小单位bit 在计算机二进制系统中: bit (位) :数据存储的最小单元. 简记为b,也称为比特(bit),每个二进制数字0或1就是一个位(bit),其中,每 8bit = ...
- 一道int与二进制加减题
int dis_data = 32769; if( dis_data > 0x7fff) dis_data -= 0xffff; printf("%d\n",dis_dat ...
- WindowsPhone-GameBoy模拟器开发六--[转]指令系统实现必读:补码
网上有同行写了些好文章,在此就不现丑了,贴上连接,放在这里为了补充系列的完整性 计算机为什么选用二进制补码 为什么补码重要?因为计算机中内存.寄存器里面存的数都是用补码表示的!
随机推荐
- 360若真入股HTC 到底是谁来拯救谁
到底是谁来拯救谁" title="360若真入股HTC 到底是谁来拯救谁"> 我总是持有一种观点,那就是拯救是相互的.就像老师拯救"堕落"学生, ...
- [Golang]字符串拼接方式的性能分析
本文100%由本人(Haoxiang Ma)原创,如需转载请注明出处. 本文写于2019/02/16,基于Go 1.11.至于其他版本的Go SDK,如有出入请自行查阅其他资料. Overview 写 ...
- jsde与gulp使用说明
jade是一款基于haml的html模板引擎,已改为pug 1.全局安装 npm install jade -g 新建一个jade文件夹,再建一个后缀名为.jade的文件编辑.jade文件 jade ...
- useful_tool
记录工作学习中遇到的经典好用的工具软件. 工作篇 AxeSlide斧子演示 AxeSlide是PPT的良好替代品,跨平台,基于Html5 2D/3D技术开发.动画特效等效果十分不错.工具提供很多免费模 ...
- epoll的原理和用法
设想一个场景,有100万用户同时与一个进程保持着TCP连接,而每一时刻只有几十个或几百个TCP连接是活跃的(接收到TCP包)也就是说,在每一时刻进程只需要处理这100万连接中的一小部分连接,那么,如何 ...
- 图形用户界面(GUI)应用程序开发——菜鸟的第一步
参考资源:贺老师博文 在看完贺老师的博文后,我就照葫芦画瓢的做了个求三角形面积的程序.这是我写的一篇所用时间最长博文(两个多小时,真心挺累,或许是我太笨吧),为了尽可能详细的把步骤写明白我截了二十一张 ...
- 关于图数据库HugeGraph的百万,千万,亿量级测试
1.Hugegraph测试硬件 1.1.本机硬件 本机测试hugeGraph版本:0.10.4 后置存储数据库:rocksdb,1TB的普通硬盘 1.2.测试服务器硬件 测试服务器hugegraph版 ...
- sql05
1.Ado.net Ado.net是一组由微软提供的使用C#操作数据库的类库 2.连接 首先引入: using System.Data.SqlClient; 需要使用连接字符串进行连接 using S ...
- 如何使用API提交转码任务?
摘要: 当常规的转码工作流无法满足用户的场景时,需用户自己判断业务逻辑,并使用API提交转码任务.例如:并不是所有的视频都需要转码,不同视频需要设置不同的转码配置.本文将介绍API提交转码任务的方法. ...
- 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/ZRjGGy 可交互视频 此视频是可 ...