• C#采用的是“四舍六入五成双”、上取整、下取整


    c# 四舍五入、上取整、下取整

    Posted on 2010-07-28 12:54 碧水寒潭 阅读(57826) 评论(4) 编辑 收藏

    在处理一些数据时,我们希望能用“四舍五入”法实现,但是C#采用的是“四舍六入五成双”的方法,如下面的例子,就是用“四舍六入五成双”得到的结果:

    double d1 = Math.Round(1.25, 1);//1.2
    double d2 = Math.Round(1.24, 1);//1.2
    double d3 = Math.Round(1.26, 1);//1.3
    double d4 = Math.Round(1.35, 1);//1.4

    为了用C#来实现“四舍五入”,我写了下面的函数:

    复制代码
    代码
         /// <summary>
    /// 实现数据的四舍五入法
       /// </summary>
    /// <param name="v">要进行处理的数据</param>
    /// <param name="x">保留的小数位数</param>
    /// <returns>四舍五入后的结果</returns>
    private double Round(double v, int x)
    {
    bool isNegative = false;
    //如果是负数
    if (v < 0)
    {
    isNegative = true;
    v = -v;
    }

    int IValue = 1;
    for (int i = 1; i <= x; i++)
    {
    IValue = IValue * 10;
    }
    double Int = Math.Round(v * IValue + 0.5, 0);
    v = Int / IValue;

    if (isNegative)
    {
    v = -v;
    }

    return v;
    }
    复制代码

    经过简单的测试,上面的函数能实现对数据的四舍五入法。

    Math.Round ()在四舍五入时有个问题:   

    Math.Round(2.5,0) = 2;   

    Math.Round(3.5,0) = 4;

    2.5应该等于3才对!

    在ASP中也存在这个问题,不过ASP中还有个FormatNumber可以用,但目前还不知道怎么使用?

    解释:

    Math.Round()准确的说,这个函数不是四舍五入,而是四舍六入五凑偶,就是说小于4或大于6的该舍该入是没有争议的,而5处在正中间,如果四舍五入则会造成数据的整体偏差,所以采取的原则是:如果舍入位为5,则舍入后最后一位为偶数,这是国际惯例。

    现在做的项目都要5入,解决方法:

    目前做法是: 

    如:(3.45*10+0.5)取整,再除以10

    C# 中没有四舍五入函数,事实上我知道的程序语言都没有四舍五入函数,因为四舍五入算法不科学,国际通行的是 Banker 舍入法 Banker 's rounding(银行家舍入)算法,即四舍六入五取偶。事实上这也是 IEEE 规定的舍入标准。因此所有符合 IEEE 标准的语言都应该是采用这一算法的 

    Math.Round 方法默认的也是 Banker 舍入法 在 .NET 2.0 中 Math.Round 方法有几个重载方法 

    Math.Round(Decimal, MidpointRounding) 

    Math.Round(Double, MidpointRounding) 

    Math.Round(Decimal, Int32, MidpointRounding) 

    Math.Round(Double, Int32, MidpointRounding) 

    将小数值舍入到指定精度。MidpointRounding 参数,指定当一个值正好处于另两个数中间时如何舍入这个值 

    该参数是个 MidpointRounding 枚举 

    此枚举有两个成员:

    AwayFromZero 当一个数字是其他两个数字的中间值时,会将其舍入为两个值中绝对值较大的值。 

    ToEven 当一个数字是其他两个数字的中间值时,会将其舍入为最接近的偶数。 

    所以,要实现四舍五入函数,对于正数,可以加一个 MidpointRounding.AwayFromZero 参数指定当一个数字是其他两个数字的中间值时其舍入为两个值中绝对值较大的值,例: 

    Math.Round(3.45, 2, MidpointRounding.AwayFromZero) 

    不过对于负数上面的方法就又不对了 

    因此需要自己写个函数来处理 

    double ChinaRound(double value, int decimals) 

      if (value < 0) 
      { 
        return Math.Round(value + 5 / Math.Pow(10, decimals + 1), decimals, MidpointRounding.AwayFromZero); 
      } 
      else 
      { 
        return Math.Round(value, decimals, MidpointRounding.AwayFromZero); 
      } 


    有些时候不一定要用四舍五入的,可能需要上取整或下取整:

    Math.Ceiling()和Math.Floor 

    Math.Ceiling(3.1)=4;    
    Math.Floor(3.9)=3;

    取天板值与地板值,与"四舍五入"无关。其实Floor的结果与(int)相同,因此也可以这样写Math.Floor((double)2/3+0.5)

    floor 和 ceil是math unit 里的函数,使用前要先 Uses Math。

    trunc 和 round 是system unit 里的函数,缺省就可以用。

    floor 直接往小的取,比如 floor(-123.55)=-124,floor(123.55)=123

    trunc 直接切下整数,比如 trunc(-123.55)=-123, floor(123.55)=123

    ceil 直接往大的取,比如 ceil(-123.55)=-123, ceil(123.55)=124

    round 计算四舍五入,比如 round(-123.55)=-124,round(123.55)=124

    C#取整函数向上取整实例

    int a = 5; 

    int b = 2;   

    lbl.Text = Convert.ToString(Math.Ceiling((double)a / (double)b)); 

     
    分类: .NET C#
  • 相关阅读:
    Window安装Redis并设置为开机启动
    大佬为你揭秘微信支付的系统架构,你想知道的都在这里了
    想要设计自己的微服务?看这篇文章就对了
    破局人工智能:构建AI,与腾讯云一起探索语音应用场景
    巧用机器学习定位云服务器故障
    重磅发布 | 黑镜调查:深渊背后的真相之「DDoS 威胁与黑灰产业调查报告」
    5分钟内看懂机器学习和深度学习的区别
    如何防范和应对Redis勒索,腾讯云教你出招
    Redis勒索事件爆发,如何避免从删库到跑路?
    作为一个编程新手,我再也不怕Flink迷了我的眼!
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4872704.html
Copyright © 2020-2023  润新知