用 Java 表示货币价值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/285680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 12:32:24  来源:igfitidea点击:

Representing Monetary Values in Java

javacurrencybigdecimal

提问by dshaw

I understand that BigDecimal is recommended best practice for representing monetary values in Java. What do you use? Is there a better library that you prefer to use instead?

我知道 BigDecimal 是在 Java 中表示货币价值的推荐最佳实践。你用什么?有没有你更喜欢使用的更好的库?

采纳答案by ninesided

BigDecimalall the way. I've heard of some folks creating their own Cashor Moneyclasses which encapsulate a cash value with the currency, but under the skin it's still a BigDecimal, probably with BigDecimal.ROUND_HALF_EVENrounding.

BigDecimal一路。我听说有些人创建了他们自己的CashMoney用货币封装现金价值的类,但在皮肤下它仍然是一个BigDecimal,可能带有BigDecimal.ROUND_HALF_EVEN四舍五入。

Edit:As Don mentions in his answer, there are open sourced projects like timeandmoney, and whilst I applaud them for trying to prevent developers from having to reinvent the wheel, I just don't have enough confidence in a pre-alpha library to use it in a production environment. Besides, if you dig around under the hood, you'll see they use BigDecimaltoo.

编辑:正如 Don 在他的回答中提到的,有像timeandmoney这样的开源项目,虽然我为他们试图阻止开发人员重新发明轮子而鼓掌,但我对使用 pre-alpha 库没有足够的信心它在生产环境中。此外,如果你周围挖在引擎盖下,你会看到他们使用BigDecimal

回答by Ken Gentle

BigDecimalor another fixed point representation is what is generally needed for money.

BigDecimal或另一种定点表示通常是金钱所需要的。

Floating point (Double, Float) representations and calculations are inexact, leading to erroneous results.

浮点 ( Double, Float) 表示和计算不准确,会导致错误结果。

回答by Bill K

If you are just using dollars and cents, I'd use a long (offset by 2 decimal places). If you need more detail, big decimal may be the way to go.

如果您只使用美元和美分,我会使用 long (偏移小数点后两位)。如果您需要更多细节,大十进制可能是要走的路。

Either way, I'd probably extend the class to have a .toString() that uses the correct format, and as a place to put other methods that might come up (For a long, multiplying and dividing will go awry if the decimal isn't adjusted)

无论哪种方式,我都可能会扩展该类以获得一个使用正确格式的 .toString(),并作为放置其他可能出现的方法的地方(很长一段时间,如果小数点不是,乘法和除法就会出错'未调整)

Also, if you use define your own class and interface, then you can replace the implementation at will.

此外,如果您使用定义自己的类和接口,那么您可以随意替换实现。

回答by Pyrolistical

You have to be so careful when dealing with time and money.

在处理时间和金钱时,你必须非常小心。

When you are working with money, I hope everybody should know never to use a float or a double.

当你和钱打交道时,我希望每个人都应该知道永远不要使用浮点数或双数。

But I am unsure about BigDecimal.

但我不确定 BigDecimal。

In most cases you'll be fine if you just keep track of cents in a int or long. This way you never deal with a decimal place.

在大多数情况下,如果你只是在 int 或 long 中跟踪美分,你会没事的。这样你就永远不会处理小数位。

You only display dollars when you print it. Always work with cents internal using integers. This may be tricky if need to divide or need to use Math.abs().

打印时只显示美元。始终使用整数在内部使用美分。如果需要除法或需要使用 Math.abs(),这可能会很棘手。

However, you might care able half a cent, or even one hundredth of a cent. I don't know what's a good way to do this. You might just need to deal with thousandth of cents and use a long. Or maybe you'll be forced to use BigDecimal

但是,您可能会在乎半分钱,甚至百分之一。我不知道这样做的好方法是什么。您可能只需要处理千分之一美分并使用 long。或者你可能会被迫使用 BigDecimal

I would do a lot more reading on this, but ignore everybody who starts talking about using a float or double to represent money. They are just asking for trouble.

我会在这方面做更多的阅读,但忽略所有开始谈论使用浮点数或双倍数来代表货币的人。他们只是自找麻烦。

I feel my advice isn't complete, so please put more though into it. You are dealing with dangerous types!

我觉得我的建议不完整,所以请多加点。你正在处理危险的类型!

回答by Kozyarchuk

Creating a Money class is the way to go. Using BigDecimal( or even an int) underneath. Then using Currency class to define rounding convention.

创建一个 Money 类是要走的路。在下面使用 BigDecimal(甚至是 int)。然后使用 Currency 类来定义舍入约定。

Unfortunately without operator overloading Java makes it quite unpleasant creating such basic types.

不幸的是,如果没有运算符重载,Java 就很难创建这样的基本类型。

回答by Dónal

There is a better library, timeandmoney. IMO, it far superior to the libraries provided by the JDK for representing these 2 concepts.

有一个更好的图书馆timeandmoney。IMO,它远优于 JDK 提供的用于表示这两个概念的库。

回答by lindelof

Definitely not BigDecimal. There are so many special rules for rounding and presentation that you have to worry about.

绝对不是 BigDecimal。舍入和表示有很多特殊规则,您必须担心。

Martin Fowler recommends the implementation of a dedicated Moneyclass to represent currency amounts, and that also implements rules for currency conversion.

Martin Fowler 建议实现专用的Money类来表示货币金额,并且还实现了货币转换规则。

回答by lindelof

You can use the DecimalFormat class when ultimately displaying a currency value. It provides localization support and is pretty extensible.

您可以在最终显示货币值时使用 DecimalFormat 类。它提供本地化支持并且非常可扩展。

回答by Per Arneng

I would encapsulate BigDecimal in Money class that also has a currency just as someone mentioned above. The important thing is that you do an extreme amount of unit tests and especially if working with different currencies. Also it is a good idea if you add a convinient constructor that takes a string or a factory method that does the same so that you can write your tests something like this:

我会将 BigDecimal 封装在 Money 类中,正如上面提到的那样,它也有一种货币。重要的是您要进行大量的单元测试,尤其是在使用不同货币时。此外,如果您添加一个接受字符串的方便构造函数或执行相同操作的工厂方法,那么这也是一个好主意,以便您可以编写如下测试:

   assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));

回答by I?aki Ibarrola Atxa

It can be useful to people arriving here by search engines to know about JodaMoney: http://www.joda.org/joda-money/.

对于通过搜索引擎到达这里的人来说,了解 JodaMoney 很有用:http: //www.joda.org/joda-money/