用mysql浮点型表示十进制数字



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

示例:如果我存储了一个价格为$ 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类型不能准确地表示我的值?

不应该选择返回5.01000022888184 ?

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

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

我认为这就像数据库存储数字一样简单但是一旦你操纵它,它就会在IEEE 754形式中使用

参见前面的问题(oracle相关)oracle Floats vs Number

真正的问题是你不能这样做:

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

MySQL中存储的float的值为unknowable

这是一个巨大的错误,但是他们不愿意修复它。Decimal和Double也有类似的问题。唯一的修复方法是为模式

中的字段指定精确的精度。
ALTER TABLE `test` change `test` `test` FLOAT(10,2)

但是在计算精度不太明确的地方(例如:任何分数)