数值数据在计算机中的存储
参考:
一般数值数据包括整数和实数。数值数据在计算机中表示主要关心三个方面:进位计数制、定/浮点表示、二进制编码。
进位计数制:
- 十进制:0, 1, 2, 3, 4, 5, 6, 7, 8, 9
- 二进制:0, 1
- 八进制:0, 1, 2, 3, 4, 5, 6, 7
- 十六进制:0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
进制转换(R进制):整数部分,除R取余,上右下左;小数部分,乘R取整,上左下右。
简便方法:
835=512+256+64+2+1=>1101000011
0.6875=0.5+0.125+0.0625=>0.1011(小数点在计算机中如何表示)
定、浮点表示(解决小数点问题)
定点数:约定机器中所有数据的小数点位置固定不变,通常将定点数表示成纯小数(小数点固定在数值部分的最高位之前)或纯整数(小数点固定在数值部分的最后面)。定点小数用来表示浮点数的尾数部分;定点整数用来表示整数。整数又分为带符号整数和无符号整数。有无符号位决定了数值的表示范围。
浮点数:利用指数达到浮动小数点的效果,将实数X表示为\(X=(-1)^s \times M \times R^E\)。S取0或1,决定X的符号;M是一个二进制定点小数,称为X的尾数(mantissa);E是一个二进制定点整数,称为X的阶或指数(exponent);R是基数(base),计算机中取2(以前有4或16)。
浮点数在计算机中的表示通常遵循IEEE 754标准:
单精度采用( 32bit):1个符号位,8位阶码,23位尾数;
双进度采用(64 bit):1个符号位,11位阶码,52位尾数。
前面已经说到,浮点数的尾数部分采用定点小数来表示,而浮点数的阶采用定点整数的移码来表示(即加上偏置,在移码部分介绍)。
二进制编码(解决正负号问题)
下面来说明原码、补码、移码和反码(少用)。
原码
第一位是符号位,正号用0表示,负号用1表示,其他位直接由十进制数转化为二进制数。下表是4位二进制数与十进制数的对应关系。
十进制 | 二进制 | 十进制 | 二进制 |
---|---|---|---|
0 | 0000 | -0 | 1000 |
1 | 0001 | -1 | 1001 |
2 | 0010 | -2 | 1010 |
3 | 0011 | -3 | 1011 |
4 | 0100 | -4 | 1100 |
5 | 0101 | -5 | 1101 |
6 | 0110 | -6 | 1110 |
7 | 0111 | -7 | 1111 |
问题:
-
可以发现0的表示不唯一,+0(0000)和-0(1000)表示不相同;
-
+/-运算方式不统一:\(1+2=0001+0010=0011\)(正确);\(1-2=0001-0010=0001+1010=1011\)(错误),需要对符号位进行处理
补码
一个负数的补码等于对应的整数各位取反、末尾加一。
变形补码(4's comlement):双符号,用于存放可能溢出的中间结果。
十进制 | 补码 | 变形补码 | 十进制 | 二进制取反 | 补码 | 变形补码 |
---|---|---|---|---|---|---|
0 | 0000 | 00000 | -0 | 1111 | 0000 | 00000 |
1 | 0001 | 00001 | -1 | 1110 | 1111 | 11111 |
2 | 0010 | 00010 | -2 | 1101 | 1110 | 11110 |
3 | 0011 | 00011 | -3 | 1100 | 1101 | 11101 |
4 | 0100 | 00100 | -4 | 1011 | 1100 | 11100 |
5 | 0101 | 00101 | -5 | 1010 | 1101 | 11101 |
6 | 0110 | 00110 | -6 | 1001 | 1110 | 11110 |
7 | 0111 | 00111 | -7 | 1000 | 1111 | 11111 |
8 | 1000 | 01000 | -8 | 0111 | 1000 | 11000 |
注意比如十进制数8的表示,值太大会占用符号位(溢出),用4位补码无法表示,但换用变形补码就能够保留符号位以及最高数值为。
从表中可以看到,补码的+0和-0表示唯一,下面来分析减法运算的问题。
先来看模运算的例子。
钟表时针指向10点,要想将它拨到6点,有两种方法:倒拨4格(10-4=6)或顺拨8个(10+8=18 18mod12=6 ,这里用到了模运算)。
另一个例子:一个4位十进制数的模运算系统,只能用加法,计算9828-1928
\(9828-1928\\=9828+(10^4-1928)(负数取反)\\=9828+8072\\=17900 \mod 10^4(舍弃高位1)\\=7900\)
计算机中的运算器就是这样的模运算系统(因为计算机的运算器只有有限位,假设n位,则运算结果只能保留低n位)。
如计算:
\(0111\;1111-0100\;0000\\=0111\;1111+(2^8-0100\;0000)\\=0111\;1111+1100\;0000\\=10011\;1111(\mod 2^8)\\=0011\;1111\)
即利用补码能将减法运算当作加法运算来处理。
移码
将数值加上一个偏置常数(Excess/bias)。编码位数为n时,bias通常取 2^(n-1) 或2^(n-1)-1(如IEEE 754)。 例如,n=4时:
十进制 | 二进制移码 |
---|---|
-8(+8) | 0000 |
... | .... |
0(+8) | 1000 |
... | ... |
+7(+8) | 1111 |
注意到:0的移码表示唯一。当bias为\(2^{n-1}\)时,移码和补码仅第一位不相同。
浮点数的阶用移码表示。为什么呢?便于浮点数加减运算时対阶操作(比较大小)。如:\(1.01 \times 2^{-1}+ 1.11 \times 2^3\),対阶的时候,-1的补码为111,3的补码为011,此时比较两者大小:\(111<011?\),不能直接比较。而阶数都加上常数,即-1+4=3补码为011,3+4=7补码为111,此时比较:011<111,结果是直接成立的。