• 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、尽量避免使用浮点数做比较,如果愣是比较,可以先做精度处理或者先转换成整型再比较。

  • 相关阅读:
    Android -- SEGV_MAPERR,SEGV_ACCERR
    使用预编译库PREBUILT LIBRARY官方说明
    Application.mk文件官方使用说明
    Android.mk文件官方使用说明
    ndk-build官方使用说明
    cocos中lua使用shader实例
    Wifi 攻击科普
    狠心把小米笔记本的操作系统换成了kali
    端口转发正反向链接 NC 和 SSH下的用法
    linux下无回显可将回显发送到服务器
  • 原文地址:https://www.cnblogs.com/shanfeng1000/p/12398446.html
Copyright © 2020-2023  润新知