计算机中小数的表示方法-定点数和浮点数
计算机中的小数有两种表达方式:定点数表示法和浮点表示法。这两种表示方法定义与小数点有关,是为了解决小数点表示的问题。定点表示法中的小数点固定在某一个位置上;浮点表示法中的小数点的位置可以浮动,不固定在具体的位置上。
定点数表示法
定点数格式:约定小数点固定在某一个固定位置上。由于约定的小数点位置固定不变,小数点就不再使用 “ . ” 表示。小数点位置固定在哪一位都可以,但是通常将数据表示为纯小数或纯整数。
假设用n+1位字来表示定点数x。第1位是符号位放在最左边,0表示正数,1表示符数;剩余位表示尾数。这样,就得出了定点数表示的数据格式。 
定点小数(纯小数)
对于定点小数,小数点固定在符号位的后面。
数值范围:
一般来说,如果最末位x0=1,前面各位都为0,则数的绝对值最小,即|x|min= 2^(-n)。
如果各位均为1,则数的绝对值最大,即|x|max=1-2^(-n)。
所以定点小数的表示范围是:2^(-n)≤|x|≤1 - 2^(-n)。
定点小数绝对值的最大值计算:2^(-1) + 2^(-2) + ... + 2^(-n) = 1 - 2^(-n)。
定点整数(纯整数)
对于定点整数,小数点位于最低位X0的后边。
数值范围:
定点整数绝对值的最大值计算:2^0 + 2^1 + ... + 2^(n-1) = 2^n - 1,固表示范围 -(2^n - 1) ~ (2^n - 1)。
浮点表示法
浮点数即小数点的位置可以浮动的数, 比如:
123.45 = 1.2345 * 10 ^ 2
= 1234.5 * 10 ^ -1
= 0.12345 * 10 ^ 3虽然这里的小数点位置改变了,但因为分别乘上了不同的10的次幂,所有计算的值并没有改变。
通常,浮点数被表示为 N = S * r ^ j,S为尾数,j为阶码,r是基数。以基数 r = 2 为例,数N可以写成下面不同的形式:
(N)2 = 11.0101
= 0.110101 * 2 ^ 10
= 1.10101 * 2 ^ 1
= 1101.01 * 2 ^ (-10)
= 0.00110101 * 2 ^ 100为了提高数据精度以及便于浮点数的比较,在计算机中规定浮点数的尾数用纯小数形式,所以上例中0.110101 * 2 ^ 10和0.00110101 * 2 ^ 100这两种形式都是可以采用的。当尾数最高位为1的时候,叫做规格化数,即0.110101 * 2 ^ 10为浮点数的规格化形式。浮点数表示成规格化形式后,其精度最高。
浮点数表示形式:
阶码j反映浮点数的范围和小数点的位置;尾数S反映浮点数的精度。尾数的数符代表浮点数的正负。
浮点数的表示范围:
设浮点数阶码的数值位取m位,尾数数值位取n位,范围表示如下:
当阶码数值部分和尾数数值部分都为1时,数的绝对值最大:(2 ^ (2 ^ m - 1) ) * (1 - 2 ^ (-n));
当尾数最后一位是1,其他位都是0时,数的绝对值最小:2^(-(2^m-1)) * 2^(-n);
所以浮点数的表示范围为:2^(-(2^m-1)) * 2^(-n)≤|x|≤(2 ^ (2 ^ m - 1) ) * (1 - 2 ^ (-n))。
当浮点数的阶码大于最大阶码时,称为上溢,此时机器一般会停止运算,进行中断溢出处理;当浮点数的阶码小于最小阶码时,称为下溢,此时溢出的绝对值很小,通常将尾数各位置为0,机器可以继续运行。
常见的浮点数阶码和位数的分配如下:
- 短实数,总位数32位,阶码8位(含阶符1位),尾数24位(含数符1位);
- 短实数,总位数64位,阶码11位(含阶符1位),尾数53位(含数符1位);
- 临时实数,总位数80位,阶码15位(含阶符1位),尾数64位(含数符1位)。
IEEE 754 标准
计算机使用IEEE 754标准表示浮点数。IEEE 754 标准简化了浮点数的表现形式,浮点数统一写成 (-1)^S * M * 2^E 。
- 符号位(Sign,S):表示浮点数是正数还是负数。当S=0时,表示这个浮点数为正值;S=1表示这个浮点数为负值。
- 尾数位(Mantissa,M):表示基数部分,即数值部分,尾数位决定了浮点数的精度(有效数字),取值范围:1≤M<2。
- 阶码位(Exponent,E):表示指数部分,所以又称指数位,表示一个数的幂值,指数位决定了浮点数的取值范围和绝对值最小的非零数,其在内存中是以无符号形式存储的。
对于float单精度浮点数,第1位为符号位S,接着8个位存储E指数位,最后23个位存储有效数字M。![IEEE754_01.jpg IEEE754_01.jpg]()
对于double双精度浮点数,第一位为符号位S,接着11个位存储E指数位,最后52个位存储有效数字M。![IEEE754_02.jpg IEEE754_02.jpg]()
尾数M
对于尾数M,1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。 IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的 xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位, 将第一位的1舍去以后,等于可以保存24位有效数字。
指数E(阶码)
- 将E存入内存:首先E为一个无符号整数,这意味着,如果E为8位,它的取值范围为0~255开区间;如果E为11位,它的取值范围为0~2047开区间。但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即 10001001。
- 将浮点数取出内存:将E加上127/1023存入内存后,在使用时要将E、M再取出来,但E的情况不同取出的方法不同。在一般情况下将指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。比如:0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为 1.0*2^(-1),其阶码为-1+127=126,表示为 01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示形式为:0 01111110 00000000000000000000000。
- E全为0:这时浮点数的指数E等于1-127(或者1-1023),有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
- E全为1:这时如果有效数字M全为0,表示±无穷大(正负取决于符号位s)。
总结
由于内存限制,计算机表示的数据是有限的,一旦超出数据的表示范围,就会发生溢出或计算精度问题。了解小数的存储方式以及表示的数值范围,可以帮助我们更好的解决问题,发掘问题的本质。

