单精度浮点数的存储方式
首先,所有的数据在计算机中以二进制来存储的数据。
所以,先将浮点数数据转换为二进制表示。
例如:36.7:
整数部分的二进制表示是很简单的:除二取余法(将整数除以二取出余数,最后倒序排列)
36的二进制表示为100100
小数部分的二进制表示:将小数部分乘以2,取整数部分的值,知道小数部分为0或位数满了
0.7的二进制表示为101100(1100无限循环)。。。。。
最终37.6的二进制表示为100100.10110011001100...
32位存储方式
在IEEE754标准出现以前,每个厂商对于浮点的存储方式各不相同。
这个32位二进制的存储被分为了3部分:第一部分为符号位(1位),第二部分指数位(23-30,共8位),第三部分尾数位(0-22共23位)
首先我们将二进制的小数点移动到小数点前仅1位
100100.10110011001100... = 1.0010010110011001100... * 2 ^ 5
左移为正数,右移为负数。
这个移动的位数 + 127(偏移量)就是指数位:5 + 127 = 132 => 10000100
移动后的结果的小数部分为尾数位,因为移动的结果的整数部分一定是1,所以将忽略这个整数部分即0010010110011001100...
所以36.7的存储方式为
0 10000100 00100101100110011001101
通过理解float的存储方式知道为什么不存储金额了吧。
float的存储方式一定导致尾数部分是有误差的,因为尾数位的存储是有一定尾数限制。这种误差会导致因为float数据之间操作而扩大。例如两个误差的数据相加,结果的误差将会放大。所以对于对于精确度比较敏感的数据例如金额,航天军工数据是不能使用float的。
两个小工具:
1.浮点数的IEEE754内存状态
https://www.h-schmidt.net/FloatConverter/IEEE754.html
2.进制转换网站
https://tool.oschina.net/hexconvert