为何不能用浮点型表示金额?

参考博客:blog.csdn.net/bruce128/ar…java

在java中,通常来讲,咱们的单精度float和双精度double已经能够知足咱们的大部分需求了。可是无论是float和double都会出现浮点的偏差,而这点偏差在通常状况下并不影响咱们的使用。.net

可是,在金融行业,一个小小的精度偏差,可能会致使成千上万的损失,甚至严重点来讲,可能会有牢狱之灾。所以,咱们必须去严格的计算每个小数点的值,不能出现任何偏差。3d

也所以,出现了咱们如今的这个问题,为何不能用float和double等等等的浮点型来表示金额?cdn

看代码: blog

结果为:

能够看出,随着运算数量的上升,明显看到偏差的产生。这是float类型的运算,若是是double类型的话,那么偏差将会更大。ci

这是第一个缘由,使用float和double会出现偏差,这在金融行业基本上不被容许的。get

那么,仅仅是这个缘由吗?博客

还有一个缘由,咱们要向float和double这两个基础数据类型中找寻。it

这个问题和float和double在java中规定的数据长度有关。32位的浮点数float由3部分组成:1比特的符号位,8比特的阶码(exponent,指数),23比特的尾数(Mantissa,尾数)。这个结构会表示成一个小数点左边为1,以底数为2的科学计数法表示的二进制小数。浮点数的能表示的数据大小范围由阶码决定,可是可以表示的精度彻底取决于尾数的长度。而64位的浮点数double是1比特的符号位,11比特的阶码(exponent,指数),52比特的尾数(Mantissa,尾数)。io

因而,就会出现以下代码的状况:

结果为:
缘由:

long的最大值是2的64次方减1,须要63个二进制位表示,即使是double,52位的尾数也没法完整的表示long的最大值。不能表示的部分也就只能被舍去了。因此致使了添加了10亿次以后,数值依然没有变化,由于添加的数值都被舍去了。

那么,应该怎么办呢?

JDK提供了一个BigDecimal的类,这个类能够表示任意精度的数字。

相关文章
相关标签/搜索