Java BigDecimal 的四舍五入使用问题

2022 年 8 月 31 日
 dramakevinzz

又来论坛求助 V 友了,今天在使用 BigDecimal 四舍五入保留一位小数的时候遇到了很神奇的问题。

double num1 = 5.95;
double num2 = 6.95;
double num3 = 7.95;
double num4 = 8.95;
double num5 = 9.95;
double num6 = 5.43;
System.out.println(new BigDecimal(num1).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()); // 6.0
System.out.println(new BigDecimal(num2).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()); // 7.0
System.out.println(new BigDecimal(num3).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()); // 8.0
System.out.println(new BigDecimal(num4).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()); // 8.9
System.out.println(new BigDecimal(num5).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()); // 9.9
System.out.println(new BigDecimal(num6).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue()); // 5.4

8.95 和 9.95 四舍五入应该是 9.0 和 10.0 ,但是输出不是这样,但是 5.95 、6.95 、7.95 又不是这样,这是为啥捏

1963 次点击
所在节点    问与答
11 条回复
mango88
2022 年 8 月 31 日
System.out.println(new BigDecimal(num1));
System.out.println(new BigDecimal(num4));
这俩你输出看一下就明白了,浮点数的精度问题

另外构建 BigDecimal 对象推荐用字符串构造
new BigDecimal("5.95")
new BigDecimal("8.95")
这样
dqzcwxb
2022 年 8 月 31 日
mango88
2022 年 8 月 31 日
或者 BigDecimal.valueOf(double)
dqzcwxb
2022 年 8 月 31 日
dramakevinzz
2022 年 8 月 31 日
@mango88 感谢!这种方法真的就解决了,但是还想请教一下 [浮点数的精度问题] 这个是指什么?可以再解释一下嘛?或者可以再细说一下方向,我查一下,谢谢
dramakevinzz
2022 年 8 月 31 日
@dqzcwxb 感谢,这张图确实看着就比较明显了,我记得好像是浮点数的存储和表象并不一致,导致有可能类型 X.9+Y.1 最后并不是 Z.0 这种情况,看 CSAPP 的时候记得这里好像是和 IEEE 设计有关,我再翻一下书,查查,感谢
mineralsalt
2022 年 8 月 31 日
因为浮点的问题, 我现在设计金额相关字段的时候, 全部用 int
dramakevinzz
2022 年 8 月 31 日
@mineralsalt 金额用 int 吗?这个和日常使用场景怎么契合呢?比如小数,分小数和整数分开存储吗?
wu67
2022 年 9 月 1 日
@dramakevinzz 用分为单位, 就不存在小数了
VeryZero
2022 年 9 月 1 日
BigDecimal 源码注释里有解释,建议使用字符串构造
mineralsalt
2022 年 9 月 2 日
@dramakevinzz #8 所有金额都用分进行数据库存储, 前端展示的时候格式化一下就行了, 只要存到数据库, 就是分为单位

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.xtra.eu.org/t/876836

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX