如何在java中将美元金额转换为美分?

Nit*_*tal 0 java currency bigdecimal

我有以下程序(取自SO链接What is the best way to conversion Dollars (Big Decimal) in Cents (Integer) in java?),它将美元转换为美分。然而,输出并不符合我的预期。

电流输出:

12345
8
Run Code Online (Sandbox Code Playgroud)

预期输出:

12345
9
Run Code Online (Sandbox Code Playgroud)

主程序.java

public class Main {

    private static final BigDecimal x100 = new BigDecimal(100);
    static List<BigDecimal> nums = new ArrayList<>();
    static BigDecimal a = new BigDecimal(123.45);
    static BigDecimal b = new BigDecimal(0.09);

    public static void main(String[] args) {
        nums.add(a);
        nums.add(b);
        for (BigDecimal usd : nums) {
            BigDecimal rounded = usd.setScale(2, BigDecimal.ROUND_DOWN);
            BigDecimal bigDecimalInCents = rounded.multiply(x100);
            int cents = bigDecimalInCents.intValueExact();
            System.out.println(cents);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

Bas*_*que 5

太长了;博士

使用字符串,而不是数字文字。

new BigDecimal( "123.45" )
Run Code Online (Sandbox Code Playgroud)

避免浮点

double在构建BigDecimal.

new BigDecimal( 123.45 )  // <-- Passing `double` primitive
new BigDecimal( 0.09 )
Run Code Online (Sandbox Code Playgroud)

当你以为你正在通过时,123.45你实际上正在通过一些更像是的东西123.4500000000000028421709430404007434844970703125。而不是0.09你传递的东西更像是0.0899999999999999966693309261245303787291049957275390625.

您违背了将 BigDecimal 与货币一起使用的真正目的,即避免浮点类型在确定其小数部分时固有的不准确性。

Java 类型、、、float都使用浮点技术。浮点技术牺牲了计算执行速度的准确性。对于某些游戏、图形和科学/工程目的有好处,但不利于赚钱。FloatdoubleDouble

BigDecimal使用浮点技术。因此计算的执行速度要慢得多,但结果是准确的。

解决方案:构造时避免浮点BigDecimal。使用字符串。

new BigDecimal( "123.45" )
new BigDecimal( "0.09" )
Run Code Online (Sandbox Code Playgroud)