【问题标题】:how to fix double precision issue in java [duplicate]如何解决java中的双精度问题[重复]
【发布时间】:2023-03-23 06:40:02
【问题描述】:

可能重复:
Java floats and doubles, how to avoid that 0.0 + 0.1 + … + 0.1 == 0.9000001?

如何克服 java android 中双倍乘法的精度问题?请注意,我正在将字符串值转换为双精度值。

例如:当我将两个双精度值相乘时:

double d1 = Double.valueOf("0.3").doubleValue() * Double.valueOf("3").doubleValue();
System.out.println("Result of multiplication : "+d1);

我得到以下结果:0.8999999999999999

我得到的一些结果是。

0.6*3=1.7999999999999998;
0.2*0.2=0.04000000000000001;
等等

我希望得到以下结果,而不是上述结果。

0.3*3=0.9;
0.6*3=1.8;
0.2*0.2=0.04;

请记住,我并不是要将它四舍五入到最接近的整数。

【问题讨论】:

  • 您尝试过 DecimalFormat 吗?示例:(new DecimalFormat("0.00").format(doubleValue*1.00000));

标签: java android double double-precision


【解决方案1】:

您确实应该使用java.math.BigDecimal 以避免任何精度问题,并始终使用 BigDecimal(String) 构造函数。

BigDecimal result = new BigDecimal("0.3").multiply( new BigDecimal("3.0") );

【讨论】:

  • 我认为使用 BigDecimal 会避免 任何 精度问题是不准确的。归根结底,我们必须做出一些牺牲才能在有限的内存中表示尽可能大的数字范围。
  • @AdrianMouat,我很确定如果您按照我指定的方式使用 BigDecimal(使用 BigDecimal(String) 构造函数构造它),您将避免任何精度问题而无需牺牲。
  • 在给定的例子中,当然。然而,仍然必须有限制。
  • @AdrianMouat 唯一的限制是可用内存。 BigDecimal 不使用浮点数,因此它不会像双精度数那样存在这个问题。
  • @EJP,这与我所说的并不矛盾。当您的数字无法以十进制表示(例如 1/3)时,BigDecimal 似乎会引发异常。所以我想你在这里牺牲了精确度的灵活性。
【解决方案2】:

问题不在于乘法。它以 Double.valueOf("0.3") 开头。该值不能以浮点数精确表示。您应该使用 java.math.BigDecimal,还应该在 Google 上找到一个标题为“每个计算机科学家都应该了解的浮点知识”的页面。

【讨论】:

  • @downvoter 你在开玩笑。请解释一下如何用浮点数精确表示 0.3。
【解决方案3】:

不幸的是,我不知道有一种简单的方法可以完全按照您的要求进行操作。

就像 Strelok 所说,如果您需要精确的结果,则不应使用浮点类型。但是,对于大多数目的,只需指定输出的舍入精度就足够了。以下代码接近但不完全符合您的要求:

System.out.printf("Result of multiplication : %.1g\n", d1);

有关 printf 语法的更多信息,请参阅the java.util.Formatter documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多