当前位置: 首页 > 知识库问答 >
问题:

如果使用double将一种货币值转换为另一种货币值,然后再转换回另一种货币值,您可能损失的最大精度是什么?

袁鸿畴
2023-03-14

我知道由于基数2计算而产生的双倍问题:

var total: Double = 0.1
total *= 0.1
total /= 0.1
println(total) // 0.10000000000000002

我明白BigDecimal应该用于货币相关的计算,但在我的情况下,小的精度损失是可以接受的,因为我需要做的所有货币计算都是将货币C1转换为货币C2,然后再转换回货币C1。唯一的问题是,当我用5个十进制精度向客户显示结果时,转换后的C1的两个值应该匹配。

现在我想弄清楚,在最坏的情况下,这个值可能会在这个转换上漂移多少?哪些数字可能导致最坏的情况?

共有3个答案

夏华藏
2023-03-14

我建议永远不要在任何地方存储或转移C2金额。相反,存储或转移C1金额和汇率。这样,您可以随时计算和显示C2金额,并且您将始终拥有确切的原始C1值。

如果您必须存储C2,然后重新计算C1,只要您使用四舍五入而不是截断就可以了,因为您有可能重新计算的结果会0.0199999999999。(正如@Andreas在他的回答中指出的,以这种方式支持的位数是有限制的。)

单昊穹
2023-03-14

二进制64中的double如果正确地四舍五入到小数点,将保留15位有效小数。

使用固定位置数学:小数点后有15位有效小数,运算需要5位小数,小数点左边还有10位。

x,xxx,xxx,xxx.xxxxx
赵飞雨
2023-03-14

您可以阅读双精度浮点的描述:

指数的11位宽允许表示具有10^−308和10^308之间的十进制指数的数字,具有完整的15-17位十进制数字精度。

因为你想要5个分数位数,这意味着你最多可以有10个整数位数。

或者你可以测试一下。有时经验证据更具说服力:

java prettyprint-override">double value = 0.00009;
while (true) {
    String nextDown = String.format("%.5f", Math.nextDown(value));
    String nextUp   = String.format("%.5f", Math.nextUp(value));
    if (! nextDown.equals(nextUp))
        break; // loss of precision to 5 decimals
    System.out.printf("Good: %.5f%n", value);
    value = value * 10 + 0.00009;
}
System.out.printf("Bad: %.5f%n", value);

输出

Good: 0.00009
Good: 0.00099
Good: 0.00999
Good: 0.09999
Good: 0.99999
Good: 9.99999
Good: 99.99999
Good: 999.99999
Good: 9999.99999
Good: 99999.99999
Good: 999999.99999
Good: 9999999.99999
Good: 99999999.99999
Good: 999999999.99999
Good: 9999999999.99999
Bad: 99999999999.99997

是的,10是好的,11是坏的。

 类似资料:
  • 我必须将所有产品的正常价格和销售价格(超过10000)从美元改为印度卢比。客户希望所有的价格都应该通过乘以64.72(当前美元对印度卢比的汇率)以印度卢比转换。它是在产品创建期间以美元输入的。但是现在客户坚持从各地换成INR 请注意,更改数据库中的原始价格是必须的,我们没有使用任何货币转换工具来显示使用转换工具的最终用户。 例如,假设产品价格为100美元,现在批量更新后,数据库中的价格也应为647

  • 在我们继续之前,我们需要先来知道“菲亚特”或“菲亚特货币”的含义。 菲亚特货币由政府宣布为其控制的领土内的法定货币。仅因政府监管或法律而具有价值的菲亚特货币不受黄金或白银等实物商品的支持。法定货币的价值来自供需关系和发行政府的稳定性,而不是支持它的商品的价值。它基于经济的信念和信誉。大多数现代纸币都是法定货币。 每个加密货币的新手都想知道如何兑现比特币或从比特币中提取到法定货币(美元,欧元,印度卢

  • 问题内容: 有没有一种方法可以将int转换为货币格式。我可以连接“ $”符号,但是如何将放入其中呢?像将int = 1000变成$ 1,000一样? 还是有一个功能可以完成所有工作?是否有字符串替换? 问题答案: FORMAT()函数:http : //dev.mysql.com/doc/refman/5.5/zh- CN/string- functions.html#function_forma

  • 我试过... 但那就不允许便士条目了。 我想要增量按钮控制在英镑上升,但仍然想要输入便士的能力。 谢谢,1DMF

  • 问题内容: 我在字符串变量中有美元 我如何将其转换为小数而不是字符串,以便可以对其进行操作,例如向其中添加美元? 问题答案: 有一个简单的方法:

  • 这是一篇加密货币的入门文章,是写给没有接触过比特币、加密货币的小伙伴的入门指南,接下来的内容,都将与加密货币相关。 前言 “加密货币就是货币”听起来挺“白痴的”。想想背后的意思,言外之意就是“加密货币可能不是货币”,就非常值得玩味了。事实上,在我接触的很多朋友当中,一开始认为后者的更多。包括我自己,也是经过探究一段时间之后,才认定这个结论的。 惯性定律不仅存在于物质世界,也存在于人类的认知世界。人