文章目录
- 《计算机系统基础》——数据的表示
- 移码
- 整数
- 无符号整数 (Unsigned integer)
- 带符号整数(Signed integer)
- 测试代码
- 浮点数
- 表示范围
- IEEE 754标准
- 例子
- 规格化数
- 0
- +∞/-∞
- 非数
- 非规格数
《计算机系统基础》——数据的表示
移码
🚀🚀移码:将每一个数值加上一个偏置常数。通常,当编码位数为n时,bias取 2n-1 或 2n-1-1。
🚀🚀比如当n为4的时候,bias= 23 ,所以-8 = 0000B(-8 + 8)。之所以要用移码,主要是为了便于浮点数加减运算时的对阶操作。
整数
🚀🚀说起整数,相信大家肯定有所了解,作为我们最早使用的数据类型,但是它并没有那么简单,接下来我们就来介绍一下。
无符号整数 (Unsigned integer)
🚀🚀在整数中,我们用 LSB来表示最低有效位,用MSB来表示最高有效位,之所以这样规定,主要就是在我们的整数中,一般最高位用来表示符号位。而无符号整数则没有符号位,所有的位都用来计数。我们常在一个数的后面加一个“u”或“U”表示无符号数。
带符号整数(Signed integer)
🚀🚀而带符号整数,则是用MSB来表示数符(0–正数,1–负数),并且是采用补码来表示带符号整数。
🚀🚀若同时有无符号和带符号整数,则C编译器将带符号整数强制转换为无符号数。
🚀🚀要注意带符号整数是采用补码来表示的,所以才能得到表中的数值。
🚀🚀在不同的规则下,编译器处理默认常量的类型也不一样,具体如下所示。
🚀🚀这个是c90,无符号整型与long long类型有所区别。
🚀🚀在C99规则下,则没有无符号整型。
测试代码
#include<stdio.h>
void main ()
{
int x=-1 ;
unsigned int u = 2147483648 ;
printf ("x = %u = %d\n", x, x) ;
printf ("u = %u = %d\n", u, u) ;
if (-2147483648<2147483647)
printf ("-2147483648 < 2147483647 is true\n") ;
else
printf ("-2147483648 < 2147483647 is false\n") ;
if (-2147483648-1 < 2147483647)
printf ("-2147483648-1 < 2147483647\n") ;
else if(-2147483648-1 == 2147483647)
printf ("-2147483648-1 == 2147483647\n") ;
else
printf ("-2147483648-1 > 2147483647\n") ;
}
🚀🚀如果在C90标准下,2147483648为unsigned int型,因此 “-2147483648 < 2147483647”按无符号数比较, 10……0B比01……1B大,结果为false。
🚀🚀而在ISO C99标准下 ,2147483648为long long型,因此 “-2147483648 < 2147483647”按带符号整数比较,10……0B比01……1B小,结果为true。
🚀🚀最后在C90运行结果如下所示。
x = 4294967295 = -1
u = 2147483648 = -2147483648
-2147483648 < 2147483647 is false
-2147483648-1 == 2147483647
浮点数
🚀🚀在我们学习浮点数之前,我们需要简单回想一下的科学计数法,因为我们的浮点数表示方法与科学计数法是类似的,接下来我们会详细的进行介绍。
表示范围
🚀🚀我们首先看一下32位浮点数的存放格式,我们可以看到,我们的第0位S,是用来存放符号位的,一般用1表示负数,用0表示正数;然后第1~8位为8位移码表示阶码E(偏置常数为128);然后第9 ~31位为24位二进制原码小数表示的尾数M。
🚀🚀肯定有人有疑问了,9 ~ 31明明只有23个数,为什么能够表达24位呢?其实答案很简单,因为规格化尾数的小数点后第一位总是1,故规定第一位默认的“1”不明显表示出来。
🚀🚀所以,我们就能得到32位浮点数能够表示的范围了,当阶码与尾数都为1的时候,尾数就是0.11…1 ,也就是(1-2-24) ,然后阶码就是(28 - 1)- 128。以此类推,我们也能得到最小的正数。需要我们注意的是,原码是对称的,所以32位浮点数表示的范围关于原点对称。
🚀🚀我们也能发现一个问题,就是32位浮点数只能表示数轴上的一部分,其他部分都是属于溢出的范围。于是为了能表示更多有效数字,我们也可以规定规格化数的小数点前为1!但是在这里就不详细介绍了。
最大正数:0.11…1 x 211…1 = (1-2-24) x 2127
最小正数:0.10…0 x 200…0 = (1/2) x 2-128
IEEE 754标准
🚀🚀因为早期的计算机会各自定义自己的浮点数格式,所以为了解决不同计算机之间的数据传输,IEEE成立委员制定了浮点数标准,也就是我们现在的IEEE 754标准。目前所有通用计算机都采用IEEE 754来表示浮点数。
🚀🚀首先我们来看一看IEEE 754标准的规格化数是长什么样子的:
🚀🚀规格化数:+/-1.xxxxxxxxxxtwo x 2Exponent,规定:小数点前总是 “1”。
🚀🚀接下来我们就来简单的介绍一下,首先是第0位(Sign bit),用1表示负数,用0表示正数;然后第1~8位为8位移码表示阶码E(偏置常数为127),但是值得我们注意的就是,在SP规格化阶码范围为0000 0001 (-126) ~ 1111 1110 (127);然后第9 ~31位为24位二进制原码小数表示的尾数M,同样也是默认小数点前为0,所以就使用23位来代表24位。
🚀🚀阶码中的全0和全1用来表示特殊值!
例子
🚀🚀接下来呢,我们就讲解一个例子来加强我们的理解:已知float型变量x的机器数为BEE00000H,求x的值是多少?
- 数符部分为一,说明这个数为负数。
- 阶码为: 0111 1101B,也就是125,然后减去偏置常数127,于是得到阶码为-2.
- 尾数数值部分为:1 + 2-1 + 2-2 = 1.75。(1是默认的,然后前两位1分别是2-1 + 2-2 )
- 最后得到这个数值为:-1.75x2-2 = - 0.4375。
规格化数
🚀🚀我们前面介绍的都是针对规格化形式的数,那么还有一些我们没有介绍的,接下来就针对这些数进行一个介绍。
0
🚀🚀当我们的阶码和尾数都为0的时候,用来表示0,但是值得注意的是,这个地方是区分+0和-0的。
+∞/-∞
🚀🚀当阶码为全1,尾数为全0的时候这个时候表示的无穷,也是有正无穷和负无穷的区别的。而且在这里面,无穷也是可以参与运算的。
非数
🚀🚀当程序中出现一些不允许的运算时,得到的结果就是非数(NaN),比如:Sqrt (- 4.0)。这个时候就是阶码全为1,尾数不全为0.
非规格数
🚀🚀非规格化数,其实就是规格的数无法表达的数,所以他们就是阶码为0,尾数不全为0。也就是0.0…0x2-126~ 0.1…1x2-126。
🚀🚀对于非数值数据我们就不介绍了,感兴趣的同学可以去了解一下。