【问题标题】:Incrementing value in a loop yields different (wrong) value? [duplicate]在循环中增加值会产生不同(错误)的值? [复制]
【发布时间】:2026-01-09 01:00:01
【问题描述】:

我几乎一整天都在试图弄清楚为什么会这样并且循环不断将其递增 0.01 直到它是一个整数,但它永远不会停止,调试它我注意到随着循环的进行,数字变得越来越不准确,导致它最终变为 0.0000066。
我想也许该变量可能已经在其他地方以某种方式被访问过,所以我只是在一个空的“主”程序中创建了它:

float value = 0;
for (int i=0; i<100; i++) {
    value += 0.01f;
}
System.out.println(value); // Displays 0.99999934
System.out.println(value == 1); // Just in case it's displaying wrong in println (displays false)

为什么这最后不是 1?我认为这与数据类型无关,因为我正在向浮点数添加浮点数。

【问题讨论】:

  • @MadProgrammer 0-99 仍然是 100 次迭代。 100 * 0.01 = 1
  • @MadProgrammer 不,它会像预期的那样运行 100 次。执行&lt;= 100 将进行 101 次迭代。
  • 长话短说:不要检查浮点数或双精度数是否相等。正如您刚刚发现的那样,它(通常)不起作用。这就是这些数据类型的工作方式。长篇大论,请查看@RohitJain 提供的链接
  • @JanDoerrenhaus 这个故事的简短版本是一条不幸的捷径。平等是问题程序中唯一有效的部分。 0.01f 不能“工作”,+ 不能“工作”,但 == 工作得很好。 “如果您不了解它们的行为方式,请不要使用 0.01f+”比“不要使用 ==”要好得多。

标签: java loops floating-accuracy


【解决方案1】:

Java 的浮点数遵循IEEE floating point standards,这意味着无法完美表示诸如 0.01 之类的值(它是二进制的重复十进制)。仅显示 0.01 时会出现一个不可见的小错误(转换为 String 时会四舍五入),但错误会在每次添加(或任何其他数学运算)时累积;你已经显示了可见的效果。

您可以使用两倍精度的double 来减少浮点错误,但这最终也会显示浮点错误。也可以使用BigDecimal,支持任意精度。

【讨论】:

  • 我想我会使用整数然后除法。我将不得不记住这一点,绝对希望这没有发生..
【解决方案2】:

是的,这是 IEEE specification 浮点数的问题。如果精度在您的应用程序中很重要,您应该改用 BigDecimal

【讨论】:

    最近更新 更多