浮点数实际应用场景?

Java 程序员在涉及金额的计算时,一般都会使用 BigDecimal 类型,无它,使用浮点数(float、double)太不好驾驭了,很容易出现各种想到想不到的问题!

举个例子,假如我们有一张表,用来存储用户的积分,表定义如下:

然后向这个表里插入 131072.32 的积分值,如下所示

再进行查询(我的PC上亲自测试的):

SELECT * FROM f;

结果是多少呢?

你会发现不是 131072.32 ,而是 131072.31 ,what the Fuck !?怎么回事?

我手动将数据库中这个 131072.31 改成 131072.32,然后保存,刷新一下,发现这个值还是 131072.31 !

那么,我不用 sql 直接往数据库里插入,而是用代码往数据库插入一条值是 131072.31 的数据呢?

发现数据库里存的还是 131072.31 !!

为什么呢?

我就直接说吧,其实跟这个字段的类型有关,这个字段是这样一种格式:

如上,看到没有,FLOAT(10,2) 是什么意思呢?

float(M, D) 中 M 和 D 的含义?

FLOAT(10,2) 表示一共能存 M 位,其中小数点后占 D 位。

注意,是小数点后面占 D 位,不是精确到小数点后面 D 位!也不是只存储小数点后面 D 位!

如果你将这个字段改成 FLOAT(10,3) :

你再次查询,会发现数据库中 131072.31 这个数变成了:

如果你将这个字段改成 FLOAT(10,4) :

也就是说,float(M, D) 中的 D 控制的事小数点后面“显示”几位,有可能实际存的值小数点后面好多位,但是只显示 D 位!

131072.32 中的小数部分 0.32 没法精确用二进制小数表示:

0.32D 约等于 0.0101B ,而 0.0101B 再转成十进制小数是 0.3125D ,这就导致误差了!

另外:

float(M, D) 中 M 的设置,也会影响数据展示和准确性!小数点前面的数字超过 M 的位数限制也可能会出现误差!

举例

浮点数相加,随着次数越来越多,误差会越来越大!

码先生
Author: 码先生

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注