使用mysql浮点类型表示十进制数?

时间:2011-07-28 11:37:38

标签: mysql database floating-point decimal average

我知道在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吗?

3 个答案:

答案 0 :(得分:1)

我认为它就像数据库存储数字一样简单,但是一旦你操作它,它就会用在IEEE 754表格中

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

答案 1 :(得分:1)

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

avg()行为不同的原因可能是它使用double进行计算,而5.01当然更接近舍入到 - {{1实际值比所有float值都要多,因为其中有更多值。

答案 2 :(得分:0)

真正的问题是你无法做到:

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

存储在MySQL中的浮点值是 unknowable

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

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

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