【问题标题】:Representation of decimal numbers with mysql float type?用mysql浮点类型表示十进制数?
【发布时间】:2011-07-28 11:37:37
【问题描述】:

我知道在 mysql 中将十进制值存储为浮点数是个坏主意。

示例:如果我存储价格为 5.01 美元的产品,则该数字没有精确的浮点类型表示。

如果我这样做:

CREATE TABLE IF NOT EXISTS `test` (
  `test` float NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `test` (`test`) VALUES
(5.01);

然后你运行查询

SELECT AVG( test ) 
FROM test

与该表相反,您将得到以下结果:

mysql> select avg(test) from test;
+------------------+
| avg(test)        |
+------------------+
| 5.01000022888184 |
+------------------+
1 row in set (0.00 sec)

但是,如果您只选择这样的字段:

mysql> select * from test;
+------+
| test |
+------+
| 5.01 |
+------+
1 row in set (0.00 sec)

你最终得到了正确的金额。

我的问题是:怎么可能?

如果float类型不能准确代表我的值?

select 不应该也返回 5.01000022888184 吗?

【问题讨论】:

    标签: mysql database floating-point decimal average


    【解决方案1】:

    普通选择返回 5.01 的原因是它是比任何其他浮点数更接近实际值的最短数字; MySQL 显示这个而不是将实际值转换回最接近的小数,因为在大多数情况下,用户会认为这个结果“更正确”。

    avg() 行为不同的原因可能是它使用double 进行计算,而 5.01 当然更接近四舍五入到float 的实际值而不是所有值double 值,因为这些值要多得多。

    【讨论】:

      【解决方案2】:

      我认为它就像 db 存储数字一样简单,但是一旦你操作它,它就会以 IEEE 754 形式使用

      查看之前的(oracle 相关的)问题Oracle Floats vs Number

      【讨论】:

        【解决方案3】:

        真正的问题是你做不到:

        SELECT * FROM `test` WHERE `test` = 5.01
        

        存储在 MySQL 中的浮点数的值是不可知的

        这是一个巨大的错误,但他们不愿意修复它。 Decimal 和 Double 有类似的问题。唯一的解决方法是为架构中的字段指定精确的精度

        ALTER TABLE `test` change `test` `test` FLOAT(10,2)
        

        但是你会在计算精度不明确的地方失去任何精度(例如,任何分数)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-01-01
          • 2023-04-06
          • 1970-01-01
          • 2011-05-31
          • 2012-08-10
          • 1970-01-01
          • 2022-01-05
          • 1970-01-01
          相关资源
          最近更新 更多