【问题标题】:Big float numbers weird results大浮点数奇怪的结果
【发布时间】:2013-04-27 10:20:12
【问题描述】:

在 java 中,我使用浮点数来存储数字。我选择了浮点格式,因为我同时使用整数和双精度数,其中数字不同,可能有大整数或具有不同小数位数的大双精度数。但是当我将这些数字插入数据库时​​,存储了错误的数字。例如:

float value = 0f; value = 67522665; System.out.println(value);

打印:6.7522664E7,它在数据库中存储为 67522664 而不是 67522665

【问题讨论】:

标签: java floating-accuracy


【解决方案1】:

浮点数的分辨率有限 - 大约 7 个有效数字。您会看到舍入错误。您可以使用double 以获得更高的分辨率,或者,对于精确算术,使用BigDecimal

推荐阅读:What Every Computer Scientist Should Know About Floating-Point Arithmetic

【讨论】:

  • 顺便说一下,BigDecimal 的计算速度比其他原始数据类型慢很多。
  • @Drogba - 是的,确实如此。但是,如果您需要准确性,那就是您需要付出的代价。
  • 精度有限,不准确。
  • @yshavit - 你说得对,“准确性”不是正确的词。但是“精度”也不对,因为这与可重复性有关。 (IEEE 浮点计算是完全可重复的。)我选择了“分辨率”。
  • 问题是我插入这个值的数据库中列的类型是浮点数。
【解决方案2】:

Double 和 float 存在存储问题。 How is floating point stored?

“float 和 double 类型主要是为科学和工程设计的 计算。他们执行二进制浮点运算,这是仔细 旨在在广泛的幅度范围内快速提供准确的近似值。 但是,它们不能提供准确的结果,因此不应在以下情况下使用 需要准确的结果。”

不要使用浮点数。请改用 BigDecimal。根据我对数据库的经验,他们将 NUMBER 类型的元素返回为 BigDecimal。当我使用 JDBC 获取它们时,它们是 BigDecimal 对象。

【讨论】:

    【解决方案3】:

    据我所知,这是关于二进制表示中的间隙大小(或ULP最后的单位),即连续 f 点值之间的间距。

    这个值等于:

    2^(e+1-p)
    

    e 是一个数字的实际 指数,而 p精度

    请注意,间距(或间隙)随着表示数字的值增加而增加:

    在 IEEE-754 中,精度是 p 24,所以你可以看到当 e >= 23 我们可以开始谈论浮点世界中的整数间距.

    2^23 = 8388608   --> 8388608 actually stored IEEE-754
           8388608.2 --> 8388608 actually stored IEEE-754
    

    随着数字变大,情况会变得更糟。例如:

    164415560 --> 164415552 actually stored IEEE-754
    

    参考:The Spacing of Binary Floating-Point Numbers

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多