代码之家  ›  专栏  ›  技术社区  ›  Yada

浮点舍入错误

  •  1
  • Yada  · 技术社区  · 15 年前

    从内部来看,右边的浮点表示法是怎么变为false的?

    mysql> SELECT 3.1415 + 0.9585 = 4.1, 3.1415E0 + 0.9585E0 = 4.1E0;
    +-----------------------+-----------------------------+
    | 3.1415 + 0.9585 = 4.1 | 3.1415E0 + 0.9585E0 = 4.1E0 |
    +-----------------------+-----------------------------+
    |                     1 |                           0 |
    +-----------------------+-----------------------------+
    

    结论:不要在精确数学中使用Float或Double。使用十进制。

    4 回复  |  直到 15 年前
        1
  •  2
  •   ty812    15 年前

    从未 将=与浮点一起使用,因为如果不发生舍入错误,则无法预测。始终使用<或>,取决于你想要实现什么。

    第二:这两个公式都没有错。在内部,这两个变量都在其变量中编码为最接近的二进制表示形式,这与您设置的值略有不同。

    小数点前一位是标准数字,因此使用以下所有数字。在右侧,您专门定义逗号出现的位置,从而“浪费”变量二进制表示末尾的某个部分,这会导致舍入错误(在本例中)。

        2
  •  1
  •   NDM Haresh Vidja    15 年前

    FLOAT DOUBLE 它们总是不精确的,因为它们是近似值,而不是精确值,所以不应将它们用于计算。使用 DECIMAL

        3
  •  1
  •   Abel    15 年前

    MySQL,就像几乎所有使用浮点运算的计算机实现一样,使用 IEEE-754 standard

    正如不可能用十进制写1/3,也不可能用二进制浮点写无限多个数字(考虑到计算机在时间和空间上的限制)。一个浮点使用32位,一个双精度使用64位,从数学上讲,这对于无限多个分数来说是非常小的空间。

    精确小数也存在,但限于固定范围(即没有高指数)。在MySQL中,您可以使用 DECIMAL 对于定点数字。

        4
  •  0
  •   wallyk    15 年前

    在这方面,幸运的是第一个比较准确:

    SELECT 3.1415 + 0.9585 = 4.1, 3.1415E0 + 0.9585E0 = 4.1E0;
    

    mysql> SELECT abs(3.1415 + 0.9585 - 4.1) < 0.0001, abs(3.1415E0 + 0.9585E0 - 4.1E0) < 0.0001;
    +-------------------------------------+-------------------------------------------+
    | abs(3.1415 + 0.9585 - 4.1) < 0.0001 | abs(3.1415E0 + 0.9585E0 - 4.1E0) < 0.0001 |
    +-------------------------------------+-------------------------------------------+
    |                                   1 |                                         1 |
    +-------------------------------------+-------------------------------------------+
    1 row in set (0.00 sec)
    

    选择与所涉及的值相对应的差值(我使用了0.0001)。