一、人与计算机的数字互动
码的表示,在于一种表达,计算机运算所需要的一种形式。
人有自己舒适的阅读理解习惯 ,十进制是最直观、最习惯熟悉的一种模式。同样,计算机也是如此,在计算机(或者说集成电路)的认知中,只要低电位和高点位两种形式,也就是0和1,所有衍生出二进制。为了显示、表达、储存方便,进而又有了八进制、十六进制。故而、计算机的运算是二进制的运算。
在对二进制进行运算时,要和十进制的数相匹配,同时还要表达正负,所以在把十进制数转换为二进制数之后,要加上一个符号位,就变成了原码。因为有符号位的出现,所以一个字节的8个二进制位上,只有7个位能表示值,做进一步的延伸,也就是n个二进制位上,有(n-1)个位能表达数值。
同时,衍生出两个概念:机器数和真值
机器数:一个数在计算机中的二进制的表现形式,是带符号的,用最高位的数来表示,0代表整数,1代表负数
真值:就是带符号位的机器数所对应的真正数值,区分正负。
二、机器内的数字游戏
1、加法运算:
CPU是计算机系统的运算和控制核心,其中运算器的最基本操作是加法,加法最为高效。
如果用原码进行加法运算,会涉及到符号位的处理,而且原码有两个机器零,会让计算机的基础电路设计变得十分复杂化。故而发展出了补码,反码是原码与补码进行转换的一种过渡码。
补码的引进利用了模运算在数理上对于符号位的处理,用钟表12个刻度为一个模来举例,回拨5和前调7得到的效果一样;同理,以四位带符号位的机器数为例,0(0000)为基数,模值 = 8,那么 -7(1001)前调8为 1(0001),它们除了符号位应该完全一样。这样减法就可以变成整数和一个负数模后的正数值相加,结果再反向模即可,相当于符号位就是模运算。
举个例子:1 - 6 = 1 + (-6)
-
-6 模 8 ,向前调是2,那么2 + 1 = 3,3再模 8 ,向后调是 -5 。
-
再按照尾数计算,0001 + 0010 = 0011,就是3(0011),3后调8就是-5(1011),
-
这样就和0001(1) + 1010(-6) = 1011(-5)的效果完全一样。
补码解决了两个机器零的问题,而且可以使符号位也参与运算,使得减法运算可以转换为加法运算,所以计算机中的二进制数以补码形式存储。(参考博文3及本文中的四码对应表)
2、移码与浮点数阶码
数字中除了整数,还有小数。如何把所有的数字都可以很好的表达成机器数,于是出现了定点数和浮点数的概念。
(1)定点数是小数点位置是固定的,所以能表达的数的范围较小,计算中容易溢出。
(2)浮点数中的小数点位置不固定,可以通过阶数表达更大范围的数。为了规范使用,出现了IEEE754工业标准,用符号位、指数(阶码)和尾数(原码)来组合表示。
移码:在数X上增加一个偏移量,常用来表示浮点中的阶码,通过偏移量实现小数点的左右移动,从而可以是浮点数的规范化可以实现。
3、为什么阶码的偏移量是127
3.1 阶码增加的偏移量是2^(n-1)-1,首先因为浮点数有三种特殊情况
-
P(阶码) M(尾数) 值 0000 0000 0 0 0000 0000 ≠0 非标准值 1111 1111 0 ±∞ 1111 1111 ≠0 NaN
**NaN:**即非数值,是一个特殊的数值,这个数值适用于表示一个本来要返回的操作数未返回数值的情况(这样子就不会抛出错误了)。
3.2 在阶码的0-255的区间内
如果向左移动27=(128)位后,范围是-128至127,去掉全零和全一两个特殊位后,是-127至126,,表示的真值范围是(5.87x10(-39),1.7x10^38),,小数左右两侧的精度不一样 。
如果移动的是27-1=127位,范围是-127至128;去掉全零和全一的特殊位,是-126至127,表示的真值范围是(1.175x10(-38,),3.4x10^38)。
所以,阶码的偏移值是127。
三、四位机器数的原、反、补、移码的简介及其对应表
-
原码:最高位表示正负,其余位表示数值的绝对值。
-
- 缺点:0有两种表现形式,+0和-0
-
-
反码:原码与补码之间的一种过渡码
-
补码:正数与原码相同,负数是在反码的末尾加1
-
- 优点:± 0都用同一个数表示0000
- 缺点:数值和符号位一起编码,不能从码值形式上判断真值大小
- 特点:多了一个-8。 -1-7的结果应该是-8, 在用补码运算的结果中, [1000 ]补 就是-8. 但是注意因为 实际上是使用以前的-0的补码来表示-8, 所以-8并没有原码和反码表示
-
-
移码:在数x的补码值上增加一个偏移量来表示。
-
-
机器字长为n,偏移量为2^(n-1)。
-
X(移) = 2^(n-1) + X(补码)
-
实现了真值从小到大的顺序排列:0000 = -8,最小;1111 = 7,最大。
-
-
原码 +0 1 2 3 4 5 6 7 0000 0001 0010 0011 0100 0101 0110 0111 -0 -1 -2 -3 -4 -5 -6 -7 1000 1001 1010 1011 1100 1101 1110 1111 反码 +0 1 2 3 4 5 6 7 0000 0001 0010 0011 0100 0101 0110 0111 -0 -1 -2 -3 -4 -5 -6 -7 1111 1110 1101 1100 1011 1010 1001 1000 补码 +0 1 2 3 4 5 6 7 0000 0001 0010 0011 0100 0101 0110 0111 -0 -1 -2 -3 -4 -5 -6 -7 -8 0000 1111 1110 1101 1100 1011 1010 1001 1000 移码 +0 1 2 3 4 5 6 7 1000 1001 1010 1011 1100 1101 1110 1111 -0 -1 -2 -3 -4 -5 -6 -7 -8 1000 0111 0110 0101 0100 0011 0010 0001 0000
-
四、参考博文及相关百科资料
- [运算器百度百科](运算器_百度百科 (baidu.com))
- [定点数的原码反码补码移码表示公式及范围](定点数表示方法——原码,补码,反码,移码 - Reasno - 博客园 (cnblogs.com))
- [原码反码补码详解](原码, 反码, 补码 详解 - ziqiu.zhang - 博客园 (cnblogs.com))
- [模运算百度百科](模运算_百度百科 (baidu.com))
- 浮点数阶码为什么增加127的偏移量
- [NaN非数值]((4条消息) NaN,非数值_sinat_36841379的博客-CSDN博客)
- [NaN百度百科](NaN(数值数据类型的一类值)_百度百科 (baidu.com))
注:参考了CSDN与博客园的很多优秀的文章,结合自己的理解最终整理成文,非常感谢参考文章中各位的优秀见解和分享。