MySQL浮点计算存在的问题与解决方案

如有疑问请联系微信:onesoft007 

     在计算机中,浮点数往往很难精确表示,那么浮点数运算结果也往往难以精确表示。MySQL同样也存在这个问题,并表现在如下几个方面。

问题

1、相同的输入,可能造成不一样的输出(受CPU、编译器等影响) 

  a)下面是MySQL官方网站给出的例子

mysql> 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 |
+------+-------+------+

  当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

时间: 2024-08-10 21:18:06

MySQL浮点计算存在的问题与解决方案的相关文章

mariadb10.x启用gtid复制时提示mysql.gtid_slave_pos找不到的解决方案

mariadb10.x安装方式为yum时,当启用gtid复制方式后,一直提示mysql.gtid_slave_pos找不到的解决方案 造成的原因不详 解决方案:/usr/share/mysql/mysql_system_tables.sql是创建系统表的脚本 找到innodb_table_stats,innodb_index_stats,gtid_slave_pos表的创建方式 innodb_table_stats表的创建语句: SET FOREIGN_KEY_CHECKS=0; DROP TA

【转载】mysql 远程连接速度慢的解决方案

原文地址:http://blog.163.com/[email protected]/blog/static/16674283420110224207826/ PHP远程连接MYSQL速度慢,有时远程连接到MYSQL用时4-20秒不等,本地连接MYSQL正常,出现这种问题的主要原因是,默认安装的 MYSQL开启了DNS的反向解析,在MY.INI(WINDOWS系统下)或MY.CNF(UNIX或LINUX系统下)文件的[mysqld]下加入 skip-name-resolve这一句.连接mysql

mysql支持emoji表情存取的解决方案

让mysql支持emoji表情存取的解决方案 APP移动端无需做任何修改,服务端修改即可. 第一步:修改jdbcUrl: conn.url=jdbc:mysql://127.0.0.1:3306/eyes?zeroDateTimeBehavior=convertToNull&autoReconnect=true 第二步:mysql驱动包: mysql-connector-java-5.1.24.jar 第三步:数据库版本检查: select version() #查看mysql版本 5.6.23

MYSQL中&#39;TYPE=MyISAM&#39;错误的解决方案

create 语句后面的TYPE=MyISAM TYPE=MyISAM 和 ENGINE=MyISAM 都是设置数据库存储引擎的语句 ,(老版本的MySQL使用TYPE而不是ENGINE(例如,TYPE = MYISAM). MySQL 5.1为向下兼容而支持这个语法,但TYPE现在被轻视,而ENGINE是首先的用法. 一般地,ENGINE 选项是不必要的:除非默认已经被改变了,MyISAM是默认存储引擎. 所以直接将原来TYPE=MyISAM 改成ENGINE=MyISAM 就可以了 MYSQ

详解MySQL双活同步复制四种解决方案

目录 基于MySQL原生复制主主同步方案 基于Galera replication方案 基于Group Replication方案 基于canal方案 对于数据实时同步,其核心是需要基于日志来实现,是可以实现准实时的数据同步,基于日志实现不会要求数据库本身在设计和实现中带来任何额外的约束. 基于MySQL原生复制主主同步方案  这是常见的方案,一般来说,中小型规模的时候,采用这种架构是最省事的. 两个节点可以采用简单的双主模式,并且使用专线连接,在master_A节点发生故障后,应用连接快速切换

mysql 海量数据的存储和访问解决方案

第1章  引言 随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题.对于一个大型的互 联网应用,每天几十亿的PV无疑对数据库造成了相当高的负载.对于系统的稳定性和扩展性造成了极大的问题.通过数据切分来提高网站性能,横向扩展数据层已 经成为架构研发人员首选的方式.水平切分数据库,可以降低单台机器的负载,同时最大限度的降低了宕机造成的损失.通过负载均衡策略,有效的降低了单台机 器的访问负载,降低了宕机的可能性:通过集群方案,解决了数据库宕机带来的单点数据库不能访问的问题:通过读写

MySQL Unable to convert MySQL datetime value to System.DateTime 解决方案

Unable to convert MySQL date/time value to System.DateTime 解决方案 这个问题发生在MySQL数据里面有Date类型数据,在C#中查询出来时候时间的类型不一致而导致! 网上看了一下,找到有两种解决方案: 1.在连接字符串中加入“Allow Zero Datetime=True”: con = new MySqlConnection("server=localhost;database=test;CharSet=gb2312;pooling

Mysql主从同步延迟问题及解决方案

主从同步出现的延迟问题原因及解决方案 对于主从正常执行,相应的延迟几乎是不存在的.但是在高QPS下,主从同步却出现了比较明显的延迟情况. _________________________________________________________ 问题一:主库的从库太多,导致复制延迟 从库数据以3-5个为宜,要复制的从节点数量过多,会导致复制延迟 问题二:从库硬件比主库差,导致复制延迟 查看Master和Slave的系统配置,可能会因为机器配置不当,包括磁盘I/O.CPU.内存等各方面因素

xampp使用中mysql端口被占用问题的解决方案

如果在安装XAMPP前本机已经安装了mysql,并且添加了Windows服务中 使用xampp时,两个Mysql在Windows服务中有冲突 这意味着你之前在电脑上使用过mysql,路径.端口都被占用过了. 这种情况下XAMPP中的mysql自然是不能正常启动的, 会出现这样的提示信息 首先,尝试改变XAMPP Mysql 和Control Panel settings 的config里的端口值,依然报错 现在尝试提示信息的第二种方法(如果你以前装的不想再用的话),这个修改方法在百度经验就有不错