【问题标题】:What is the best way to convert Dollars (Big Decimal) in Cents (Integer) in java?在java中将美元(大十进制)转换为美分(整数)的最佳方法是什么?
【发布时间】:2015-08-04 13:24:37
【问题描述】:

我必须将我的 Web 应用程序与支付网关集成。我想以美元输入总金额,然后将其转换为美分,因为我的支付网关库接受以美分为单位的金额(Integer 类型)。我发现java中的Big Decimal是操纵货币的最佳方式。目前我输入 50 美元并将其转换为 Integer,如下所示:

BigDecimal rounded = amount.setScale(2, BigDecimal.ROUND_CEILING);
BigDecimal bigDecimalInCents = rounded.multiply(new BigDecimal("100.00"));
Integer amountInCents = bigDecimalInCents.intValue();

这是将美元转换为美分的正确方法还是我应该以其他方式进行?

【问题讨论】:

    标签: java integer type-conversion bigdecimal


    【解决方案1】:

    包含我以下观点的最简单的是:

    public static int usdToCents(BigDecimal usd) {
        return usd.movePointRight(2).intValueExact();
    }
    

    我推荐intValueExact,因为如果信息丢失(如果您正在处理超过 21,474,836.47 美元的交易),这将引发异常。这也可以用来捕获丢失的分数。

    我还会考虑接受一个美分和四舍五入的值是否正确。我会说不,客户端代码必须提供有效的计费金额,所以如果我需要一个自定义例外,我可能会这样做:

    public static int usdToCents(BigDecimal usd) {
        if (usd.scale() > 2) //more than 2dp
           thrown new InvalidUsdException(usd);// because was not supplied a billable USD amount
        BigDecimal bigDecimalInCents = usd.movePointRight(2);
        int cents = bigDecimalInCents.intValueExact();
        return cents;
    }
    

    【讨论】:

    • 此解决方案因负值而失败。例如,尝试 -4.56,你最终会得到 -455。
    • @YeshwanthKota 对其进行了测试,但事实并非如此。请详细说明。 System.out.println(usdToCents(BigDecimal.valueOf(-456, 2))); System.out.println(usdToCents(BigDecimal.valueOf(-4.56)));都显示-4.56
    • @weston:在上面的回复中,您尝试了 BigDecimal.valueOf(-4.56) ,它使 -4.56 成为双精度值。试试 System.out.println("Value is BigDecimal: "+usdToCents(new BigDecimal(-4.56)));并看到响应将是 -455。
    • 我认为您使用的代码与我提供的代码不同,因为我遇到了异常。 Exception in thread "main" java.lang.ArithmeticException: Rounding necessary at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4148) at java.math.BigDecimal.needIncrement(BigDecimal.java:4355) at java.math.BigDecimal.divideAndRound(BigDecimal.java:4330) at java.math.BigDecimal.setScale(BigDecimal.java:2470) at java.math.BigDecimal.longValueExact(BigDecimal.java:3090) at java.math.BigDecimal.intValueExact(BigDecimal.java:3147) at com.example.Main.usdToCents(Main.java:15)
    • @weston:谢谢
    【解决方案2】:

    您还应该考虑最小化Round-off errors

    int amountInCent = (int)(amountInDollar*100 + 0.5);
    LOGGER.debug("Amount in Cents : "+ amountInCent );
    

    上述解决方案可能会对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多