我正在编写一个带有变量 long balance
的银行程序将美分存入账户。当用户输入金额时,我有一种方法可以将美元转换为美分:
public static long convertFromUsd (double amountUsd) {
if(amountUsd <= maxValue || amountUsd >= minValue) {
return (long) (amountUsd * 100.0)
} else {
//no conversion (throws an exception, but I'm not including that part of the code)
}
}
在我的实际代码中,我还检查了 amountUsd
不超过 2 位小数,以避免无法准确转换的输入(例如 20.001 美元不完全是 2000 美分)。对于此示例代码,假设所有输入都有 0、1 或 2 位小数。起初我看着
Long.MAX_VALUE
(9223372036854775807 美分) 并假设 double maxValue = 92233720368547758.07
会是正确的,但它给了我大量的四舍五入错误:convertFromUsd(92233720368547758.07)
给出输出 9223372036854775807convertFromUsd(92233720368547758.00)
给出相同的输出 9223372036854775807我应该设置什么
double maxValue
和 double minValue
始终获得准确的返回值?
最佳答案
您可以使用 BigDecimal
作为临时持有人
如果您有一个非常大的 double(介于 Double.MAX_VALUE / 100.0 + 1
和 Double.MAX_VALUE
之间),则计算 usd * 100.0
会导致你的双倍溢出。
但既然你知道 <any double> * 100
的所有可能结果很长,你可以用 BigDecimal
作为您计算的临时持有人。
另外,BigDecimal
类定义了两个为此目的派上用场的方法:
通过使用
BigDecimal
您根本不必费心指定最大值 -> 任何表示美元的给定 double 值都可以转换为表示美分的长值(假设您不必处理美分分数)。double usd = 123.45;
long cents = BigDecimal.valueOf(usd).movePointRight(2).setScale(0).longValueExact();
注意:请记住,double 一开始就无法存储确切的美元信息。无法通过将 double 转换为 BigDecimal
来恢复丢失的信息。 .唯一的优势暂时
BigDecimal
给你的是usd * 100
的计算不会溢出。
关于java - 可准确转换为美分(多头)的最大金额(双倍),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64662114/