浮点数的表示
浮点数的表示
c语言中的浮点数:float , double , long double
首先,为什么要使用浮点方法,为什么要使用浮点数而不使用定长小数。
这是因为如果小数定长,其精度就是固定的,也就是说,这样的表示方法就会有固定长度的整数位和小数位。一般这些位数都不会被全部用到,甚至很有可能牺牲精度,或者造成空间浪费,因此,需要创造一种小数点可以移动的数字表示方法,即浮点数。
其次,如何科学的表示二进制数。
这里引入二进制的科学计数法:
十进制有科学计数法,任何十进制数都可以表示为x.xxxx*10^n(x为0-9),同理,所有二进制数也可以表示为1.xxx*2^n(x为0-1),举个例子:
1 | 101101.11101101转化为科学计数法 |
那么按照这样的思路,一个二进制数,就能表示为一个整数位定长为1,且一定是1的数字1.0110111101101(因为整数位永远是1,因此其实可以默认),和另一个整数5,代表乘2的多少次方。
然后,再加入正负的可能性,我们就可以完全的表示一个二进制数。**
1 | N=((-1)^S)*(R^E)*M |
最后,我们就可以开始设计浮点数了
S有两种取值,只需要一位;
R取值固定,不需要表示,默认即可;
E是指数(上例中的5),为一个不定长的整数(可能正,可能负),需要多位;
M一定以1开头,因此可以忽略1,直接记录小数点后面的小数(即只记录0110111101101);
我们看看官方的表示方法:


IEEE754标准(规定了浮点数的表示格式,运算规则等)
规则规定了单精度(32)和双精度(64)的基本格式.
规则中,尾数(M)用原码,指数(E)用移码(便于对阶和比较)
源码顾名思义就是二进制数直接写出来,不含符号位。
移码是什么呢?
上面说过,指数是有正负的可能性的,移码其实就是取中间数为0,减少为负数,增加为正数。
比如说:
对于32位的浮点数来说,E的位数有八位(256),因此选择127(01111111)为0,那么相应的,1就是128(10000000),-1就是126(01111110)。因此,如果给出一个值E,E-127就是指数的真实值。
同理,对于64位的浮点数来说,E的位数有11位,那么把E换算成十进制后,E-1023就是指数的真实值。
这样我们就学会如何表示一个浮点数了。
我们给出一个例子:
1 | 20.59375转化为32位数浮点表示 |