Java 8 BigDecimal 乘法方法在反转时丢失精度

sme*_*eeb 5 java precision bigdecimal

这里是 Java 8。据谷歌称:

所以我编写了这段 Java 代码:

public class MeasurementConverter {
    private static final int SCALE = 2;

    public static void main(String[] args) {
        new MeasurementConverter().run();
    }

    private void run() {
        BigDecimal hundredLbs = new BigDecimal(100.00);
        BigDecimal hundredInches = new BigDecimal(100.00);

        System.out.println(hundredLbs + " pounds is " + poundsToKilos(hundredLbs) + " kilos and converts back to " + kilosToPounds(poundsToKilos(hundredLbs)) + " pounds.");
        System.out.println(hundredInches + " inches is " + inchesToMeters(hundredInches) + " meters and converts back to " + metersToInches(inchesToMeters(hundredInches)) + " inches.");
    }

    private BigDecimal metersToInches(BigDecimal meters) {
        return meters.multiply(new BigDecimal("39.3701").setScale(SCALE, BigDecimal.ROUND_HALF_UP));
    }

    private BigDecimal inchesToMeters(BigDecimal inches) {
        return inches.multiply(new BigDecimal("0.0254").setScale(SCALE, BigDecimal.ROUND_HALF_UP));
    }

    private BigDecimal kilosToPounds(BigDecimal kilos) {
        return kilos.multiply(new BigDecimal("2.20462").setScale(SCALE, BigDecimal.ROUND_HALF_UP));
    }

    private BigDecimal poundsToKilos(BigDecimal pounds) {
        return pounds.multiply(new BigDecimal("0.45359").setScale(SCALE, BigDecimal.ROUND_HALF_UP));
    }
}
Run Code Online (Sandbox Code Playgroud)

当它运行时,会打印出:

100 pounds is 45.00 kilos and converts back to 99.0000 pounds.
100 inches is 3.00 meters and converts back to 118.1100 inches.
Run Code Online (Sandbox Code Playgroud)

而我期待它打印出来:

100.00 pounds is 45.00 kilos and converts back to 100.00 pounds.
100.00 inches is 3.00 meters and converts back to 100.00 inches.
Run Code Online (Sandbox Code Playgroud)

我所关心的是英制<->公制转换精确到小数点后两位,并且最终输出始终精确到小数点后两位。谁能看到我哪里出了问题以及解决方法是什么?

lex*_*ore 6

你把括号弄乱了。考虑一下:

kilos.multiply(new BigDecimal("2.20462").setScale(SCALE, BigDecimal.ROUND_HALF_UP));
Run Code Online (Sandbox Code Playgroud)

在这里,您首先设置2.20462结果的比例2.20,然后相乘。

现在考虑逆向转换:

pounds.multiply(new BigDecimal("0.45359").setScale(SCALE, BigDecimal.ROUND_HALF_UP));
Run Code Online (Sandbox Code Playgroud)

在这里你有效地乘以0.45。这2.2*0.45=0.99解释了结果。

您已在乘法结果上设置了比例,而不是在乘法器上设置了比例。基本上最后一个支架放错了地方。它应该是这样的:

pounds.multiply(new BigDecimal("0.45359")).setScale(SCALE, BigDecimal.ROUND_HALF_UP);
Run Code Online (Sandbox Code Playgroud)

这是更正后的代码