zoukankan      html  css  js  c++  java
  • C# double类型精度丢失问题

      我们先看一段代码,可以在控制台程序中执行看看结果  

        {
            double d = 500;
            double d1 = 233.84;
            double d2 = d - d1;
            //d2=266.15999999999997
        }
        {
            double d = 0.4;
            double d1 = d + d + d;
            //d1=1.2000000000000002
            double d2 = d * 3;
            //d2=1.2000000000000002
        }
        {
            double d = 1.2;
            double d1 = d / 0.4;
            //d1=2.9999999999999996
        }

      看到结果,你可能惊讶或者不惊讶,认为计算机计算出现这种精度问题很正常,但是当你做判断时,发现1.2!=0.4*3或者3!=1.2/0.4,你就会懵逼了  

        bool b1 = 1.2 == 0.4 * 3;//false
        bool b2 = 3 == 1.2 / 0.4;//false

      更有甚者,将计算出来的double类型直接保存在数据库,那保存的也是上面那一堆的小数,后来者看到这个也是奔溃的!

      更大的影响是在做金额运算时,我们一般都是精确到分,但是有时会计会发现自己计算出来的数据和我们系统中的对不上,我们的第一感觉也是精度问题,往往会做一个四舍五入,向上取值,向下取值等等操作,那么更大的问题来了,比如向下取值,你会发现1.2/0.4向下取整等于2!  

        double b = Math.Floor(1.2 / 0.4);//d=2

      心中一万只草泥马奔腾而过!

      float、double和decimal

      float、double和decimal是C#中表示浮点数的类型

    类型 名称 bit 有效数字 数值范围 是否基础类型
    float 单精度浮点数 32 7 ±1.5×10E−45 ~ ±3.4×10E38
    double 双精度浮点数 64 15/16 ±5.0×10E−324 ~ ±1.7×10E308
    decimal 高精度浮点数 128 28 ±1.0×10E−28 ~ ±7.9×10E28

      float和double都是基础类型,区别就是表示的数值范围和精度不一样,而decimal是C#作为补充加上来的一个类型,不是基础类型,它拥有更高的精度,但是表示的数值范围却小多了,而且计算速度相对来说要慢一些,但是也足够一般的业务需求了,比如上面的例子,如果把double都换成decimal就不会出现问题了。

      float、double和decimal都有精度丢失问题,只不过他们在丢失时的精度条件不一样,而且精度丢失了还不报异常。

      个人建议

      1、在项目中尽可能的使用decimal,虽然decimal也会出现精度丢失问题,但是一般业务需求是没问题的。

      2、当方法返回浮点类型时,或者返回的实体包含有浮点类型,那么在返回时一定要考虑要不要处理精度问题。

      3、在对外输出或者存储时,如保存到数据库,一定要根据自己的需求做个精度处理。

      4、当基础类型在不同类型之间转换时,尽可能的使用Convert类中的方法,少用强制转换。 

      5、尽量避免使用浮点数做比较,如果愣是比较,可以先做精度处理或者先转换成整型再比较。

  • 相关阅读:
    6.基础控件
    5.对话框组合
    4.对话框程序
    3. MFC原理介绍
    三星曲面显示器
    笔记本光驱接口怎么外接台式机硬盘?
    笔记本usb外接3.5寸sata台式机硬盘, 用mhdd检测不到,怎么处理?
    MHDD检测不到硬盘的解决办法
    MHDD检测电脑硬盘坏道
    一个指向指针函数的函数指针
  • 原文地址:https://www.cnblogs.com/shanfeng1000/p/12398446.html
Copyright © 2011-2022 走看看