在前文我们已经谈及过,处理订单交易、货币计算以及商品金额时,应避免使用浮点数(double/float)来定义变量。这是由于浮点数在计算机中的表示可能会引发各种问题,具体实例在前文中已有详细阐述。
“好了,让我们继续深入探讨一下吧!”
看来,《计组原理》或《计算机系统》这门课的复习是势在必行了(带点幽默地打个趣)。不过说实话,长期写业务代码,确实容易让人忘记一些基础的知识。
学习过《计算机组成原理》或类似《计算机系统》这类课程的朋友们应该都知道,浮点数在计算机中的存储遵循IEEE 754 浮点数标准。这种存储方式可以形象地理解为:
它采用尾数 + 阶码的编码方式,就像我们数学课本上所学的科学计数法表示方式一样,即有效数字 + 指数位!只要给出了符号(S)、阶码部分(E)、尾数部分(M)这三个维度的信息,float和double这两种类型的浮点数在计算机中的存储结构就确定了。
关于符号部分(S)
0代表正数,1代表负数。
阶码部分(E)(指数部分)的具体情况如下:
- 对于float型浮点数,指数部分有8位,考虑可正可负,因此可以表示的指数范围为-127到128。
- 而对于double型浮点数,指数部分有11位,同样可正可负,因此可以表示的指数范围为-1023到1024。
尾数部分(M)的精度是由其位数决定的:
- float型浮点数的尾数部分有23位,换算成十进制就是2^23=8388608,因此十进制精度大约为6~7位;
- 而double型浮点数的尾数部分有52位,换算成十进制就是2^52=70496,因此十进制精度大约为15~16位。
正因为浮点数在计算机中的存储可能会产生精度丢失的问题,所以使用时必须格外小心。一旦因此出现了bug,定位问题将会非常困难。预防工作至关重要。
上面所述的是IEEE标准规定的内容,属于理论规约。那么,一个小数到底要怎么换算成二进制呢?我们需要通过实例来解释。
让我们通过一个简单的例子来看一下:
比如,将十进制小数0.875转换成二进制。我们可以分几步操作:
-
以小数点为界进行拆分
-
整数部分的转换
(此处使用“除2取余法”)进行转换。对于0.875,其整数部分为0。
-
小数部分的转换
(这里采用“乘2取整法”)进行转换。
-
合并结果
-
(经过上述步骤后)最终得到的二进制结果为0.111。
接下来看一个稍微复杂点的例子:
比如将十进制小数6.36转换成二进制。
(此处使用图示来解释更为清晰明了)...