Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 431|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-15 16:18:08 | 显示全部楼层 |阅读模式

    如有疑问请联系微信: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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-20 13:33 , Processed in 0.065466 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表