概述
/*******************************
*FileName: 为什么MySQL的浮点数类型不够精准?
*Author: weibo
*Version: v1.0
*Date: 2016.5.15
*Description: 为什么MySQL的浮点数类型不够精准?
**********************************/
MySQL浮点数类型不精准,因此,在一些对精确度要求较高的项目中,不要使用浮点数。为什么不精确呢?下面通过一个简单的实例来分析。
1、创建一个表,指定price字段为DOUBLE浮点数类型
CREATE TABLE demo.goodsmaster
(
barcode TEXT,
goodsname TEXT,
price DOUBLE,
itemnumber INT PRIMARY KEY AUTO_INCREMENT
);
2、插入两条数据
INSERT INTO demo.goodsmaster( barcode, goodsname, price)VALUES ( '0001', '书', 0.57);
INSERT INTO demo.goodsmaster( barcode, goodsname, price)VALUES ( '0002', '笔', 0.46);
INSERT INTO demo.goodsmaster( barcode, goodsname, price)VALUES ( '0003', '笔', 0.27);
3、查看数据,并把两个商品价格相加
SELECT * from demo.goodsmaster;
SELECT SUM(price) FROM demo.goodsmaster;
期待值:0.57+0.46+0.27=1.1
实际结果为:1.0999999999999999'
当我们需要以通过数值对比为条件进行查询,一旦出现误差,就查不出需要的结果了:
SELECT goodsname,SUM(price) FROM demo.goodsmaster GROUP BY goodsname having SUM(price)=1.1;
4、为什么会出现这种情况?
我们分析下MySQL对浮点类型数据的存储方式。FLOAT(4字节)和DOUBLE(8字节)都采用二进制的方式来进行存储数据,比如 9.625,用二进制来表达,就是 1001.101,或者表达成 1.001101×2^3如果尾数不是0 或5,比如 9.624,你就无法用一个二进制数来精确表达,结果只好在取值允许的范围内进行四舍五入。
5、 如何解决?
浮点数类型是把十进制数转换成二进制数存储,DECIMAL是把十进制数的整数部分和小数部分拆开,分别转换成十六进制数,进行存储。这样,所有的数值,就都可以精准表达了,不会存在因为无法表达而损失精度的问题。MySQL 用 DECIMAL(M,D)的方式表示高精度小数。其中,M 表示整数部分加小数部分,M<=65。D 表示小数部分位数,D<M
6、方案验证
(1)把字段“price”的数据类型修改为 DECIMAL(5,2)
ALTER TABLE demo.goodsmaster MODIFY COLUMN price DECIMAL(5,2);
(2)查看数据,并把两个商品价格相加
7、总结
(1)浮点类型取值范围大,但是不精准,适用于需要取值范围大,又可以容忍微小误差的科学计算场景,比如计算化学、分子建模、流体动力学等。
(2)定点数类型取值范围相对小,但是精准,没有误差,适合于对精度要求极高的场景,比如涉及金额计算的场景。
最后
以上就是明亮月亮为你收集整理的为什么MySQL的浮点数类型不够精准?(实例证明)的全部内容,希望文章能够帮你解决为什么MySQL的浮点数类型不够精准?(实例证明)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复