关于Java 中 BigDecimal multiply() 方法的问题

Questions about BigDecimal multiply() method in Java

提问人:yoyoyoni1004gmailcom 提问时间:9/5/2023 最后编辑:Mark Rotteveelyoyoyoni1004gmailcom 更新时间:9/5/2023 访问量:69

问:

我一直在尝试避免在 Java 中使用 BigDecimal multiply() 方法时精度损失。

请查看下面的示例代码。

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;

public class HelloWorld{

 public static void main(String []args){
 
     double result = 0;
     NumberFormat formatter = new DecimalFormat("0.####################");
     formatter.setGroupingUsed(true);
 
     //10000000000
     //17911250000
     String strRt = formatter.format(10000000000.0);
     String strIrt = formatter.format(17911250000.0);
 
     System.out.println(strRt);
     System.out.println(strIrt);
 
     result = new BigDecimal(strRt).multiply(new BigDecimal(strIrt)).doubleValue();
 
    System.out.println(formatter.format(result));
 }

}

预期结果:

10000000000
17911250000
179112500000000000000

控制台中的结果:

10000000000
17911250000
179112499999999980000

有没有其他方法可以获得精确的结果?

java 精度 bigdecimal

评论

6赞 Jon Skeet 9/5/2023
我强烈怀疑问题出在调用上,而不是结果。我建议你首先把这些方面分开 - 打印调用的结果,我怀疑这将是你所期望的。doubleValue()multiply()multiply
2赞 user207421 9/5/2023
乘法中没有精度损失,但转换为 .解决方案:不要。BigDecimaldouble

答:

3赞 RoToRa 9/5/2023 #1

的重点是避免(以及所有其他原始数字类型)缺乏精度。然而,你正在使用 s 来读取(但也创建)s,从而重新引入缺乏精确度的问题。BigDecimaldoubledoubleBigDecimal

DecimalFormat直接支持,所以不需要阅读.此外,最好避免使用 s 来创建输入值。BigDecimaldoubleValuedouble

 NumberFormat formatter = new DecimalFormat("0.####################");
 formatter.setGroupingUsed(true);

 String strRt = "10000000000";
 String strIrt = "17911250000";

 System.out.println(strRt);
 System.out.println(strIrt);

 BigDecimal result = new BigDecimal(strRt).multiply(new BigDecimal(strIrt));

 System.out.println(formatter.format(result));

评论

2赞 Holger 9/5/2023
顺便说一句,当未设置分组大小时,它不起作用,并且指定大量可选的小数数字对 OP 示例的整数也没有影响。所以这个格式化程序的结果没有什么不同formatter.setGroupingUsed(true)System.out.println(result);