Java:如何计算代表金钱的double值中包含的小数位数?

对于使用Java制作的更改应用程序,我在计算double值中的小数位数时遇到问题。

double值表示money,因此我的所有操作都必须在对原始值进行操作后将12.58之类的双值存储为12.5797886。 为了抵消这种影响,我选择使用String,就像这样:

String amountString = String.valueOf(amount); String decimals = amountString.substring(amountString.indexOf('.') + 1); 

所以,如果金额是12.58,我获得58而不是57978 ……

我的问题涉及大量,就像12849561476651.2501535这样的金额在科学记数法中转换,同时存储在一个双。 所以金额的双倍值将是1.284956147665125E13

不幸的是,我不能只计算点后的数字,并在位置13之后取一切。在这样的情况下,原始小数2501535在第三个位置包含0,位置13之后的结果四舍五入到25。

我找到了一些解决方案,对于想要在没有科学记数法的情况下打印小数值的人,他们使用.printf(%f,…)或类似的东西。

但是,如果可能的话,我如何计算双值中包含的小数位数并处理存储问题和科学记数法?

我必须能够知道是否有超过2个小数。 此外,如果你有一个非常高性能的解决方案,即使它是一个复杂或奇怪的解决方案,它会很棒。

谢谢

不要使用double或float存储货币,或存储任何需要精确的十进制数,因为double和float可能不准确。

您可以使用BigDecimal或使用int或long并自己跟踪小数点。

有关这方面的更多信息,请参阅Joshua Bloch 撰写的有效Java中的“项目48:避免浮动和双重,如果需要确切答案”部分: http : //uet.vnu.edu.vn/~chauttm/e-books/java /Effective.Java.2nd.Edition.May.2008.3000th.Release.pdf

不要使用浮动或双重进行金融操作。 最好使用BigDecimalBigDecimal为您提供所需的精度。 来自javadoc:

任意精度的有符号十进制数

由于双精度的内部二进制表示的近似,double将产生错误。 此外,对于非常小的值,它可能会生成很难找到的错误。

你不能。 浮点没有小数位。 它有二进制位置,并且它们与小数位无法相称。 如果要小数位,则必须使用小数基数。

使用BigDecimal.

编辑在您自此答案后添加的段落以及您现在已删除的段落中,您声明该号码来自UI。 在这种情况下,它在那一点上是一个String ,它已经在radix-10中,所以你应该只计算String小数位数而不是将它转换为double。