小数的存储跟其他类型数据的存储方式有很大的不同,我们通常用科学技术法来表示很大或者很小的数,即用一个尾数(Mantissa),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。比如123.456 用十进制科学计数法可以表达为 1.23456× 10^2 ,其中1.23456 为尾数,10为基数,2为指数。
浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。
浮点数是将特定长度的连续字节的所有二进制位分割为特定宽度的符号域,指数域和尾数域三个域,其中保存的值分别用于表示给定二进制浮点数中的符号,指数和尾数。这样,通过尾数和可以调节的指数(所以称为"浮点")就可以表达给定的数值了。
具体的格式:
符号位 阶码 尾数 长度
float 1 8 23 32double 1 11 52 64
我们都知道浮点数在32位机子上有两种精度,float占32位,double占64位。
将一个小数写成二进制数具体步骤:小数点左边整数部分的数正常计算,小数部分的数乘以2,把个位数记录下来,就是小数部分的二进制码,大多数情况下,小数部分是不可能算的尽的。
举个例子:
0.5 = 0.100 0000 0000 0000 0000 0000
123.456 = 111 1011.0111 0100 1011 1100 01...
最后要写成科学计数法,整个一共是23位,如果为float型的话,第一个数必须为1,有时候把1省掉是为了增加小数位的数提高精度
IEEE规定,浮点标准用
V = (-1)s × M × 2E
形式来表示一个数,其中:
S 是符号 (sign),M 是有效数 (significand) ,指数2 的 E 次幂。
float 类型的 偏置量 Bias = 2k-1 -1 = 28-1 -1 = 127 ,
拿123.456 = 111 1011.0111 0100 1011 1100 01...来说,写成科学计数法是:1.1110 1101 1101 0010 1111 00*2^2, 补上因为左移作为小数部分的 2 位(也就是科学技术法的指数),因此偏置量为 127 + 2=129,这里的阶码就是12910,二进制就是:1000 00012。
因此,拼接起来后:
为
1000 0001 01001100110011001100110
| ← 8位 → | | ←------------- 23位 -------------→ |
加起来就是31位,还差一位符号位就是32位了。
double型的也同样如此,只不过位数不一样,double的阶码为11位,尾数为52位。