将货币值存储为 Double,但使用 BigDecimal 来计算值
目前,我们的一些 Hibernate 实体使用 Double 来存储货币金额,数据库将该值存储为数字 (10,2)。这些货币双精度金额的计算始终使用 BigDecimals 进行计算,然后将实体值设置为双精度。
示例:
Order order = new Order();
OrderLineItem line = new OrderLineItem(1.0, 450.00);
BigDecimal orderValue = BigDecimal.valueOf(line.getQty())
.multiply(BigDecimal.valueOf(line.getAmount()));
order.setOrderTotal(orderValue.setScale(2, ROUND_HALF_EVEN).doubleValue());
到目前为止,这工作得很好,但是我想知道这是否有某种舍入误差的潜在风险。
想法?
Currently some of our Hibernate entities are using Doubles to store monetary amounts, the database stores this value as a numeric(10,2). The calculation of these monetary double amounts are always calculated using BigDecimals and then the entity value is set as a double.
Example:
Order order = new Order();
OrderLineItem line = new OrderLineItem(1.0, 450.00);
BigDecimal orderValue = BigDecimal.valueOf(line.getQty())
.multiply(BigDecimal.valueOf(line.getAmount()));
order.setOrderTotal(orderValue.setScale(2, ROUND_HALF_EVEN).doubleValue());
This has worked fine so far, however I'm wondering if this has any potential risks for some sort of rounding error.
Thoughts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
只要信息管道的每一部分都使用
BigDecimal.valueOf
且BigDecimal(double)
绝对不会在任何地方使用,那么的隐式舍入>valueOf
可能会阻止最坏的情况发生。但您真的知道 JPA 和/或 JDBC 如何在numeric(10,2)
和double
之间进行转换吗?您确定这在未来不会改变吗?另一点:
valueOf
和doubleValue
使用中间String
表示形式。在某些情况下,这可能是性能和垃圾收集问题。除此之外,还有足够多的关于 double 问题的示例 - 只需查看右侧的“相关”部分即可。或者看看这个博客,其中即使是简单的东西也会造成严重破坏。
所以情况有点像超速行驶:有些人不这样做,有些人有时会这样做,并希望什么都不会发生,而有些人......我想你明白了。
As long as every piece of your information pipeline uses
BigDecimal.valueOf
andBigDecimal(double)
is used absolutely nowhere then the implicit rounding ofvalueOf
might prevent the worst. But do you really know how JPA and/or JDBC translate betweennumeric(10,2)
anddouble
? And are you sure, that this will not change in the future?Another point:
valueOf
anddoubleValue
work with intermediateString
representations. This might be a performance and garbage collection issue in some situations.Besides of this there are enough examples for problems with
double
- simply look to the "Related" section on the right side. Or look at this blog where even simple stuff can wreck havoc.So the situation is a little bit like speeding: Some don't do it, some do it sometimes and hope nothing happens and some... I think you get it.