`

转:关于二进制补码

阅读更多

问一个基本的问题。

负数在计算机中如何表示?

举例来说,+8在计算机中表示为二进制的1000,那么-8怎么表示呢?

很容易想到,可以将一个二进制位(bit)专门规定为符号位,它等于0时就表示正数,等于1时就表示负数。比如,在8位机中,规定每个字节的最高位为符号位。那么,+8就是00001000,而-8则是10001000。

但是,随便找一本《计算机原理》,都会告诉你,实际上,计算机内部采用补码(Two's Complement)表示负数。

什么是补码?

它是一种数值的转换方法,要分二步完成:

第一步,每一个二进制位都取相反值,0变成1,1变成0。比如,00001000的相反值就是11110111。

第二步,将上一步得到的值加1。11110111就变成11111000。

所以,00001000的补码就是11111000。也就是说,-8在计算机(8位机)中就是用11111000表示。

不知道你怎么看,反正我觉得很奇怪,为什么要采用这么麻烦的方式表示负数,更直觉的方式难道不好吗?

昨天,我在一本书里又看到了这个问题,然后就花了一点时间到网上找资料,现在总算彻底搞明白了。

补码的好处

首先,要明确一点。计算机内部用什么方式表示负数,其实是无所谓的。只要能够保持一一对应的关系,就可以用任意方式表示负数。所以,既然可以任意选择,那么理应选择一种最方便的方式。

补码就是最方便的方式。它的便利体现在,所有的加法运算可以使用同一种电路完成。

还是以-8作为例子。

假定有两种表示方法。一种是直觉表示法,即10001000;另一种是补码表示法,即11111000。请问哪一种表示法在加法运算中更方便?

随便写一个计算式,16 + (-8) = ?

16的二进制表示是 00010000,所以用直觉表示法,加法就要写成:

 00010000
+10001000
---------
 10011000

可以看到,如果按照正常的加法规则,就会得到10011000的结果,转成十进制就是-24。显然,这是错误的答案。也就是说,在这种情况下,正常的加法规则不适用于正数与负数的加法,因此必须制定两套运算规则,一套用于正数加正数,还有一套用于正数加负数。从电路上说,就是必须为加法运算做两种电路。

现在,再来看补码表示法。

 00010000
+11111000
---------
100001000

可以看到,按照正常的加法规则,得到的结果是100001000。注意,这是一个9位的二进制数。我们已经假定这是一台8位机,因此最高的第9位是一个溢出位,会被自动舍去。所以,结果就变成了00001000,转成十进制正好是8,也就是16 + (-8) 的正确答案。这说明了,补码表示法可以将加法运算规则,扩展到整个整数集,从而用一套电路就可以实现全部整数的加法。

补码的本质

在回答补码为什么能正确实现加法运算之前,我们先看看它的本质,也就是那两个步骤的转换方法是怎么来的。

要将正数转成对应的负数,其实只要用0减去这个数就可以了。比如,-8其实就是0-8。

已知8的二进制是00001000,-8就可以用下面的式子求出:

 00000000
-00001000
---------

因为00000000(被减数)小于0000100(减数),所以不够减。请回忆一下小学算术,如果被减数的某一位小于减数,我们怎么办?很简单,问上一位借1就可以了。

所以,0000000也问上一位借了1,也就是说,被减数其实是100000000,算式也就改写成:

100000000
-00001000
---------
 11111000

进一步观察,可以发现100000000 = 11111111 + 1,所以上面的式子可以拆成两个:

 11111111
-00001000
---------
 11110111
+00000001
---------
 11111000

补码的两个转换步骤就是这么来的。

为什么正数加法适用于补码?

实际上,我们要证明的是,X-Y或X+(-Y)可以用X加上Y的补码完成。

Y的补码等于(11111111-Y)+1。所以,X加上Y的补码,就等于:

X + (11111111-Y) + 1

我们假定这个算式的结果等于Z,即 Z = X + (11111111-Y) + 1

接下来,分成两种情况讨论。

第一种情况,如果X小于Y,那么Z是一个负数。这时,我们就对Z采用补码的逆运算,求出它对应的正数绝对值,再在前面加上负号就行了。所以,

Z = -[11111111-(Z-1)] = -[11111111-(X + (11111111-Y) + 1-1)] = X - Y

第二种情况,如果X大于Y,这意味着Z肯定大于11111111,但是我们规定了这是8位机,最高的第9位是溢出位,必须被舍去,这相当于减去100000000。所以,

Z = Z - 100000000 = X + (11111111-Y) + 1 - 100000000 = X - Y

这就证明了,在正常的加法规则下,可以利用补码得到正数与负数相加的正确结果。换言之,计算机只要部署加法电路和补码电路,就可以完成所有整数的加法。

(完)

精彩评论:

Z = X + (11111111-Y) + 1式子可以写为Z = X - Y +100000000,这在硬件上可以理解为两部分电路来实现,第一部分是前面的X - Y(这里姑且不管计算的结果是正还是负),第二部分是X - Y计算的结果再和100000000相加,最终得到计算的结果Z, 而在8位的计算机上100000000是不能出现的,其实这时100000000就相当于00000000(舍去了最高位),然后我们再看一些计算的过程:
Z = X + (11111111 - Y) + 1
= X - Y + 100000000
= X - Y + 00000000
= X - Y
证毕。
这样我们就证明了X-Y或X+(-Y)可以用X加上Y的2的补码完成,而不必分两种情况来证明。


原链接:http://blog.csdn.net/winxieddd/archive/2009/10/08/4641534.aspx

分享到:
评论
1 楼 bukebuhao 2011-08-30  
牛逼,顶顶顶

相关推荐

    vi.zip_16进制补码_Labview 进制_labview 二进制_labview补码_二进制补码

    在本压缩包文件"vi.zip_16进制补码_Labview 进制_labview 二进制_labview补码_二进制补码"中,主要探讨的是在LabVIEW环境下进行16进制数值与二进制补码之间的转换和计算。 首先,我们来理解一下什么是进制。进制是...

    java 整数转二进制补码源代码

    整数转二进制补码的源代码 提供了两种方法:一种调用java api中的方法。另一种是自己实现的。

    二进制补码加法器实验1

    二进制补码加法器实验1主要涉及计算机硬件组成原理中的一个重要概念——补码运算。补码是一种在计算机系统中表示有符号整数的方法,它使得加法和减法运算可以通过同样的硬件电路来实现。在这个实验中,学生将通过...

    MATLAB 的二进制补码:计算十进制数的二进制补码。-matlab开发

    在计算机科学中,二进制补码是一种表示有符号整数的方法,特别是在处理负数时。MATLAB 是一种广泛使用的编程环境,它提供了强大的数学计算功能,包括对二进制补码的操作。在这个主题中,我们将深入探讨二进制补码的...

    二进制补码乘法及其FPGA实现

    ### 二进制补码乘法及其FPGA实现:深入解析与应用 #### 概述 二进制补码乘法及其在FPGA(Field-Programmable Gate Array,现场可编程门阵列)上的实现,是现代数字信号处理领域中的关键技术之一。随着大规模集成...

    二进制补码、小数的补码及运算规则

    二进制补码、小数的补码及运算规则 一、补码的概念和原理 补码是一种常见的概念,在计算机系统中,数值一律用补码来表示(存储)。补码的主要特点是:使用补码,可以将符号位和其它位统一处理;同时,减法也可按...

    数字逻辑设计及应用教学课件:2-2补码数制.ppt

    8. **基数补码表示法**:除了二进制补码,还有基数补码表示法,适用于非二进制系统,但这里主要讨论的是二进制补码。 9. **表格2-6**:这是一个十进制数与4位二进制数的对照表,用于帮助理解二进制和十进制之间的...

    matlab_用于2s补码到十进制转换器的源代码

    在计算机科学领域,二进制补码是一种表示有符号整数的方法,特别是在处理负数时。2s补码(Two's Complement)是现代计算机系统中最常用的形式。它允许我们用相同的操作处理正数和负数,使得加法、减法和其他算术运算...

    十六进制取补码转十进制

    十个八位十六进制数字,装换为二进制,然后取其补码,然后求其平均值。用c编写,代码稍微有点问题,大家可以完善下

    从十进制到二进制补码:将十进制数转换为定义大小的 2 的补码数的函数-matlab开发

    本篇文章将详细探讨如何使用 Matlab 开发一个函数,将十进制数转换成定义大小的二进制补码表示。 补码是一种在计算机系统中表示有符号整数的方式,主要用于存储和运算。补码系统能够方便地进行加减运算,同时避免了...

    二进制补码字符串:二进制定点二进制补码字符串和十进制数之间的转换。-matlab开发

    这些函数像内置的 MATLAB 函数 BIN2DEC 和 DEC2BIN 一样在二进制字符串和十进制数之间进行转换,但可以容纳负整数(通过二进制补码)和分数正负数(通过二进制补码固定点和字符串中的二进制小数点)。 请注意,许多...

    二进制补码一位乘法规律的推导

    二进制补码一位乘法规律的推导 本文将详细推导二进制补码一位乘法规律,并对其进行详细的分析和解释。 首先,需要了解计算机中表示带符号的二进制数称为“机器数”,这个数本身称为“真值”。机器数有四种表示形式...

    Hexadecimal-encoding.rar_labview_labview 补码_二进制补码

    总之,"Hexadecimal-encoding.rar_labview_labview 补码_二进制补码"这个项目提供了一个实际操作的平台,让你学习和掌握如何在LabVIEW中处理不同的数字表示法,特别是16进制到二进制的转换,以及原码、反码和补码的...

    二进制转原码反码补码 C语言源码

    /* *功能实现任意二进制数的原码 反码 补码转换 *仅仅是字符串的操作,没有进行数字操作 *对-0的操作可能有问题 *ssfshine@gmail.com */

    16进制(4位)到二进制原码、反码、补码计算

    16进制(4位)到二进制原码、反码、补码计算

    二进制原码反码补码.docx

    二进制原码反码补码知识点总结 计算机内部采用的是二进制,只有两个数字用于表示数据,即 0 和 1,所以它的进制原则是满 2 进 1。十进制用的是 0、1、2、3……9 十个数字来表示数据,它的原则是满 10 进 1。 二...

    原码补码转换的matlab程序

    将原码转换成补码,再将补码转成原码的matlab程序

    二进制 十进制 八进制 十六进制转化+原码 反码 补码

    - **十进制转八进制**:同样适用于上述方法,先转为二进制,再由二进制转八进制。 - **十进制转十六进制**:采用类似的“除16取余”法,对于小数部分,则采用“乘16取整”法。 **例题解析**: \[ (25.75)_{10} = ...

    8位二进制转BCD码.docx

    在 Verilog 语言中,二进制转换为 BCD 码是数字电路设计中的一个常见问题。BCD 码(Binary-Coded Decimal Code)是一种将十进制数值用二进制表示的编码方式。它将每个十进制数字(0-9)用四个二进制位(0000-1001)...

Global site tag (gtag.js) - Google Analytics