如何在 Java 中处理 float 的精度错误?

新手上路,请多包涵

我想知道在 Java 中修复精度错误的最佳方法是什么。正如您在以下示例中看到的,存在精度错误:

 class FloatTest
{
  public static void main(String[] args)
  {
    Float number1 = 1.89f;

    for(int i = 11; i < 800; i*=2)
    {
      System.out.println("loop value: " + i);
      System.out.println(i*number1);
      System.out.println("");
    }
  }
}

显示的结果是:

循环值:11

20.789999

循环值:22

41.579998

循环值:44

83.159996

循环值:88

166.31999

循环值:176

332.63998

循环值:352

665.27997

循环值:704

1330.5599

另外,如果有人能解释为什么它只从 11 开始并且每次都将值加倍。我认为所有其他值(或至少其中许多值)都显示了正确的结果。

像这样的问题过去曾让我头疼,我通常使用数字格式化程序或将它们放入字符串中。

编辑: 正如人们提到的,我可以使用双倍,但在尝试之后,似乎 1.89 作为双倍 792 仍然输出错误(输出为 1496.8799999999999)。

我想我会尝试其他解决方案,例如 BigDecimal

原文由 Adam Smith 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 470
2 个回答

问题不在于 Java,而在于好的标准浮点数 ( http://en.wikipedia.org/wiki/IEEE_floating-point_standard )。

您可以:

  • 使用 Double 并具有更高的精度(但当然并不完美,它的精度也有限)

  • 使用任意精度库

  • 使用数值稳定的算法并截断/舍入您不确定它们是否正确的数字(您可以计算操作的数值精度)

原文由 Bernd Elkemann 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题