MySQL浮点计算存在的问题与解决方案
2016-06-20 11:55
495 查看
如有疑问请联系微信:onesoft007
在计算机中,浮点数往往很难精确表示,那么浮点数运算结果也往往难以精确表示。MySQL同样也存在这个问题,并表现在如下几个方面。
问题
1、相同的输入,可能造成不一样的输出(受CPU、编译器等影响)
a)下面是MySQL官方网站给出的例子
mysql>
->
->
->
->
->
mysql>
->
+------+-------+------+
| i | a | b |
+------+-------+------+
| 1 | 21.4 | 21.4 |
| 2 | 76.8 | 76.8 |
| 3 | 7.4 | 7.4 |
| 4 | 15.4 | 15.4 |
| 5 | 7.2 | 7.2 |
| 6 | -51.4 | 0 |
+------+-------+------+[/code]
当i=1时,a=21.4、b=21.4,本不满足a<>b这个条件,可是MySQL仍然判定a与b不相等。
b)在本地虚拟机测试时(Centos 6.4 X86_64)
如有疑问请联系微信:onesoft007
在计算机中,浮点数往往很难精确表示,那么浮点数运算结果也往往难以精确表示。MySQL同样也存在这个问题,并表现在如下几个方面。
问题
1、相同的输入,可能造成不一样的输出(受CPU、编译器等影响)
a)下面是MySQL官方网站给出的例子
mysql> [code]CREATE TABLE t1 (i INT, d1 DOUBLE, d2 DOUBLE);
mysql>
INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
->
(2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
->
(2, 30.40, 30.40), (3, 37.00, 7.40), (3, -29.60, 0.00),
->
(4, 60.00, 15.40), (4, -10.60, 0.00), (4, -34.00, 0.00),
->
(5, 33.00, 0.00), (5, -25.80, 0.00), (5, 0.00, 7.20),
->
(6, 0.00, 0.00), (6, -51.40, 0.00);
mysql>
SELECT i, SUM(d1) AS a, SUM(d2) AS b
->
FROM t1 GROUP BY i HAVING a <> b;
+------+-------+------+
| i | a | b |
+------+-------+------+
| 1 | 21.4 | 21.4 |
| 2 | 76.8 | 76.8 |
| 3 | 7.4 | 7.4 |
| 4 | 15.4 | 15.4 |
| 5 | 7.2 | 7.2 |
| 6 | -51.4 | 0 |
+------+-------+------+[/code]
当i=1时,a=21.4、b=21.4,本不满足a<>b这个条件,可是MySQL仍然判定a与b不相等。
b)在本地虚拟机测试时(Centos 6.4 X86_64)
+------+--------------------+------+ | i | a | b | +------+--------------------+------+ | 1 | 21.400000000000006 | 21.4 | | 2 | 76.80000000000001 | 76.8 | | 3 | 7.399999999999999 | 7.4 | | 4 | 15.399999999999999 | 15.4 | | 5 | 7.199999999999999 | 7.2 | | 6 | -51.4 | 0 | +------+--------------------+------+ 2、结果受浮点数本身的精确度影响 把double改成float,结果如下
+------+---------------------+--------------------+ | i | a | b | +------+---------------------+--------------------+ | 1 | 21.400001525878906 | 21.399999618530273 | | 2 | 76.79999828338623 | 76.80000114440918 | | 3 | 7.399999618530273 | 7.400000095367432 | | 5 | 7.200000762939453 | 7.199999809265137 | | 6 | -51.400001525878906 | 0 | +------+---------------------+--------------------+
解决方案 1、decimal 在MySQL中,带有小数的精确运算可以使用decimal类型 CREATE TABLE t3 (i INT, d1 decimal(10,3), d2 decimal(10,3));
+------+---------+-------+ | i | a | b | +------+---------+-------+ | 6 | -51.400 | 0.000 | +------+---------+-------+
限制 decimal的精确表示为decimal(M,D),其中M最大为65,D最大为30。因此其表示的范围是远远小于double所能表示的范围 2、基于应用的解决方案 比如商品价格涉及到小数,用20.95元表示,那么可以把价格变成以分为单位,即变成2095。 结论 不要使用float、double以及其等价类型做精确计算。如果要在MySQL中做精确计算,推荐使用decimal或者将相关计算任务交给应用。
如有疑问请联系微信:onesoft007
相关文章推荐
- 用批处理对MySQL进行数据操作
- MySQL 主从配置
- mysql 分析查找执行效率慢的SQL语句
- mysql常用语句
- mysql 格式化日期 DATE_FORMAT,FROM_UNIXTIME,UNIX_TIME等
- MySql存储过程学习知识小结
- MySQL 时间戳转换成秒
- Nodejs mysql 数据库增、删、改、查 操作
- 如何将 JSON, Text, XML, CSV 数据文件导入 MySQL
- 合理配置MySQL缓存 提高缓存命中率
- Unix 安装MySQL
- mysql 主从踩的一个小坑
- mysql允许远程调用、数据库创建语句指定字符
- mysql-5.7.13-winx64 解压版 安装部署
- mysql Last_IO_Errno: 1593 报错
- mysql查询某字段重复的记录
- 在mysql中,DATE_FORMAT(date, format) 函数根据format字符串格式化date值。
- MySQL错误问题
- MySQL 拼接成一个字符串
- 扛得住双11的Mysql---硬件因素