java - 可准确转换为美分(多头)的最大金额(双倍)

标签 java types currency

我正在编写一个带有变量 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 maxValuedouble minValue始终获得准确的返回值?

最佳答案

您可以使用 BigDecimal作为临时持有人
如果您有一个非常大的 double(介于 Double.MAX_VALUE / 100.0 + 1Double.MAX_VALUE 之间),则计算 usd * 100.0会导致你的双倍溢出。
但既然你知道 <any double> * 100 的所有可能结果很长,你可以用 BigDecimal作为您计算的临时持有人。
另外,BigDecimal类定义了两个为此目的派上用场的方法:

  • BigDecimal#movePointRight
  • BigDecimal#longValueExact

  • 通过使用 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/

    相关文章:

    java - 使用 Swing 时出错

    java - 如何将 textView 与 Fragments Android/Java 一起使用?

    java - applicationContext.xml 文件有什么问题

    c++ - 如何将 float 转换为非标准编码

    objective-c - 如何正确显示货币 iPhone/Objective-C

    c++ - 初学者练习 : Design a Money class

    java - Spring OAuth2客户端,CSRF保护

    c# - LINQ 到数据 : Clever Type Recognition

    c++ - 为什么有些人更喜欢 "T const&"而不是 "const T&"?

    python - 在 Python 中将金额转换为印度符号