定点整数在计算机中的表示与运算

0 引言

      对于每一个刚进入大学校门的大学生来讲,计算机系统的基本常识和基本操作都是一门必修的课程。但是,多年来,这些计算机相关基础知识在您的脑海中是否还记忆得十分清楚呢?

      问题:十进制数-128在计算机中能否用8位(即一个字节的长度)二进制数来表示?如果可以,那么该怎样表示?

      为了回答这个问题,笔者特意查询了许多相关资料,在网络上也搜集了许多网友的回答,但是其中有正确的也有错误的。笔者将在本文中将相关知识整理出来,纠正网上一些错误的或概念混淆的说法,以飨读者。

1 定点整数在计算机中的表示

      在计算机中所处理的数据可以分为数值型和非数值型两类。其中,数值型数据是指数学中的代数值,具有量的含义,例如:128、-1024.84/5等;非数值型数据是指输入到计算机中的所有文字信息,没有量的含义,例如:作为字符处理的数字09,字母az,标点符号、图形、声音、视频等。

      计算机系统内部采用二进制来存储和处理所有的数据,也就是说,一切输入到计算机中的数据都是由二进制数01排列组合而成的。

1.1 机器数与真值

      在数学中,我们用正号“+”和负号“-”来区别正数和负数,而在计算机中,是采用符号位的方式来区分它们的,即:在符号位上用二进制数0来表示正数,用二进制数1来表示负数,符号位放在数字的最高位上。如果我们用8位二进制数来表示十进制数,则十进制数45-45可以分别表示为:

+450010 1101
-451010 1101

这种连同符号位一起数字化了的数就称为机器数,由机器数表示的实际值称为真值。例如:机器数0010 1101的真值为十进制数+45或二进制数+101101,机器数1010 1101的真值为十进制数-45或二进制数-101101

1.2 数的原码、反码和补码表示

      在计算机中,对于有符号的机器数通常使用原码、反码和补码三种方式来表示,其主要目的是解决减法运算。任何正数的原码、反码和补码的形式都完全相同,负数则各自有不同的表示形式。

1.2.1 原码

      正数的符号位用0表示,负数的符号位用1表示,其数值部分用二进制形式表示,这种表示方法称为原码。例如:十进制数+77-77的原码可以分别表示为

+770100 1101(原码)
-771100 1101(原码)

      用原码表示一个数字简单、直观,但是不能够用它直接对两个同符号数相减或两个不同符号数相加。例如:要计算十进制数36-45的和,如果采用原码直接相加的方式

+360010 0100(原码)
-451010 1101(原码)

1101 0001,这个机器数的符号位是1,表示负数,真值是1010001,相当于十进制数的81,结果合起来即为十进制数的-81,显然是不正确的。

      为了解决两个同符号数相减或两个不同符号数相加的计算问题,引入了反码和补码的概念。

1.2.2 反码

      正数的反码和原码相同,负数的反码是将该数字的符号位不变,其余各位依次取反得到。例如:十进制数+77-77的反码可以分别表示为

+770100 1101(原码)→0100 1101(反码)
-771100 1101(原码)→1011 0010(反码)

      不难推出,任何一个数的反码的反码等于这个数的原码。

1.2.3 补码

      正数的补码和原码相同,负数的补码是将该数字的符号位不变,其余各位依次取反,然后加1得到。即:负数的补码是其反码加1。例如:十进制数+77-77的补码可以分别表示为

+770100 1101(原码)→0100 1101(反码)→0100 1101(补码)
-771100 1101(原码)→1011 0010(反码)→1011 0011(补码)

      不难推出,任何一个数的补码的补码等于这个数的原码。

1.3 定点整数在计算机中的运算

      引入补码的概念之后,二进制数的加减法运算都可以采用加法来实现,并且两个数的“补码的和”等于它们“和的补码”。因此,在计算机中,加减法均采用补码来进行计算。例如:要计算十进制数36-45的和,应先求出它们的补码

+360010 0100(原码)→0010 0100(反码)→0010 0100(补码)
-451010 1101(原码)→1101 0010(反码)→1101 0011(补码)

将补码相加,得1111 0111,结果也为补码表示,对其再进行一次求补运算,即

1111 0111(补码)→1000 1000(补码的反码)→1000 1001(补码的补码,即原码)

得到原码1000 1001,相当于十进制数的-9,结果正确。

      由此可以看出,在计算机中的加减法运算可以统一为补码的加法运算,其符号位也参与运算,这是十分方便的。但是也应当注意,无论采用哪一种方式表示数值,当数的绝对值超过表示数的二进制位数所允许表示的最大值时,将会发生溢出,导致运算的错误。

2 8位二进制数可以表示的数值的范围

      要讨论8位二进制数可以表示的机器数的范围,首先应该明确其表示的形式是原码、反码还是补码。因为,不同的表示形式其表示的数值范围也是不同的。下面就来逐步回答在本文引言部分所提出的问题。 

2.1 原码的表示范围

      8位二进制数可以表示的数值的原码的范围,用十进制数可以表示为[-127127],其中0的表示有+0和-0两种,总计256个数字。详见下表。

2.2 反码的表示范围

      8位二进制数可以表示的数值的反码的范围和原码相同,即每一个数的原码均对应着一个反码。详见下表。

2.3 补码的表示范围

      8位二进制数可以表示的数值的补码的范围,用十进制数可以表示为[-128127],总计256个数字。在这里最特殊的是十进制数-128,它只能够用补码的形式1000 0000来表示,它的原码和反码由于超出了8位二进制数所能表示的范围,因此无法由8位二进制数来表示。

表  8位二进制数可以表示的数值的原码、反码和补码略表

 

十进制数 二进制数原码 二进制数反码 二进制数补码
127 0111 1111 0111 1111 0111 1111
126 0111 1110 0111 1110 0111 1110
125 0111 1101 0111 1101 0111 1101
…… …… …… ……
2 0000 0010 0000 0010 0000 0010
1 0000 0001 0000 0001 0000 0001
0 0000 0000 0000 0000 0000 0000
-0 1000 0000 1111 1111 (不可表示)
-1 1000 0001 1111 1110 1111 1111
-2 1000 0010 1111 1101 1111 1110
…… …… …… ……
-125 1111 1101 1000 0010 1000 0011
-126 1111 1110 1000 0001 1000 0010
-127 1111 1111 1000 0000 1000 0001
-128 (不可表示) (不可表示) 1000 0000

3 结论

      综上所述,如果有人提到8位二进制数所能表示的数值的范围,回答应该有两个,即:原码和反码的表示范围是[-127127],共256个数,其中0有+0和-0两个;补码的表示范围是[-128127],其中-128不存在原码和反码。然而在计算机中,负数全部都以补码的形式存储和参与运算,因此通常人们所说的8位二进制数所能表示的数值范围就是补码的表示范围,亦即[-128127]。

原文引用自:http://polaris2049.blog.sohu.com/108298036.html

原文地址:https://www.cnblogs.com/anduinlothar/p/2282443.html