【问题标题】:BigDecimal VS Float [duplicate]BigDecimal VS Float [重复]
【发布时间】:2021-02-13 00:45:21
【问题描述】:

我有一个从 PostGresql DB 读取数据的应用程序。该列定义为real。在 java 代码中,我将此列的值读取为BigDecimal。发生了什么,DB 中此列的值为0.18。当我读取这些数据时,java 输出显示为0.180000007。如果我在 java 中将列定义为Float,我得到的值为0.18。我没有在我的应用程序中进行任何货币计算。谁能解释一下为什么 BigDecimal 在小数点后显示这么多数字?

请参考下面的代码,我试图理解为什么 BigDecimal 在小数点后给出这么多数字:

公共类 BigDecimalTest {

public static void main(String[] args){
    float float_val = 0.18f;
    BigDecimal output = new BigDecimal(float_val);
    System.out.println("BigDecimal output is: "+ output);

    System.out.println("Float output is: "+float_val);
}

}

输出:

BigDecimal output is: 0.180000007152557373046875
Float output is: 0.18

【问题讨论】:

  • 您应该阅读您正在使用的 BigDecimal 构造函数的 JavaDoc。它清楚地指出:“这个构造函数的结果可能有点不可预测。人们可能会假设在 Java 中编写 new BigDecimal(0.1) 会创建一个正好等于 0.1 的 BigDecimal(未缩放的值 1,缩放为1),但它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 不能完全表示为双精度 (...)。因此,传递给构造函数的值并不完全等于 0.1,尽管看起来如此。 "
  • Yout float 具有完全相同的值。它只是打印不同。另见Is floating point math broken

标签: java floating-point bigdecimal


【解决方案1】:

看看下面这篇文章,了解BigDecimal 的一些常见陷阱:

  • 双重构造函数
  • 静态 valueOf(double) 方法
  • equals(bigDecimal) 方法
  • round(mathContext) 方法

https://blogs.oracle.com/javamagazine/four-common-pitfalls-of-the-bigdecimal-class-and-how-to-avoid-them

【讨论】:

    【解决方案2】:

    您可能在浮动的远端确实有一些“污迹”,但您实际上并没有显示它。但是要准确回答您关于为什么会发生这种情况的问题:

    浮点表示不精确,但动态范围很大 {-very small number ... +very large number}。

    不精确可能会在许多方面导致错误,例如转换为其他一些表示形式,例如 BigDecimal,它没有大的动态范围但非常精确。

    因此,浮点数中的许多数字无法在 BigDecimal 中按原样精确表示而不会出现错误。 BigDecimal 在我相信的构造函数中引用了这个。

    虽然你没有问,但我会提出一个建议:如果你想要一个浮点数,那么使用 java double/float 和 PostgreSQL 双精度/实数。如果你想要精度,那么将 BigDecimal 与 PostgreSQL 十进制/数字一起使用。这样你会得到更少的阻抗匹配。混合类型会得到一些意想不到的结果。

    有很多关于浮点的指南,它们可能会变得复杂: https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

    但如果您需要执行计算,您想真正了解浮点表示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-18
      • 2017-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      相关资源
      最近更新 更多