Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.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入门到精通教程
查看: 382|回复: 0

[默认分类] c# 四舍五入、上取整、下取整

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-13 14:45:30 | 显示全部楼层 |阅读模式
    在处理一些数据时,我们希望能用“四舍五入”法实现,但是C#采用的是“四舍六入五成双”的方法,如下面的例子,就是用“四舍六入五成双”得到的结果:


    1.    
    2.    
    3.     double
    4.      d1
    5.     =
    6.      Math.Round(
    7.     1.25
    8.     ,
    9.     1
    10.     );
    11.     //
    12.     1.2
    13.    
    14.     double
    15.      d2
    16.     =
    17.      Math.Round(
    18.     1.24
    19.     ,
    20.     1
    21.     );
    22.     //
    23.     1.2
    24.    
    25.     double
    26.      d3
    27.     =
    28.      Math.Round(
    29.     1.26
    30.     ,
    31.     1
    32.     );
    33.     //
    34.     1.3
    35.    
    36.     double
    37.      d4
    38.     =
    39.      Math.Round(
    40.     1.35
    41.     ,
    42.     1
    43.     );
    44.     //
    45.     1.4
    46.    
    复制代码

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

      
      
      代码
      
      
    1.    
    2.      
    3.       
    4.      ///
    5.       
    6.      <summary>
    7.      
    8.      ///
    9.       实现数据的四舍五入法
    10.         ///
    11.       
    12.      </summary>
    13.      
    14.      ///
    15.       
    16.      <param name="v">
    17.      要进行处理的数据
    18.      </param>
    19.      
    20.      ///
    21.       
    22.      <param name="x">
    23.      保留的小数位数
    24.      </param>
    25.      
    26.      ///
    27.       
    28.      <returns>
    29.      四舍五入后的结果
    30.      </returns>
    31.      
    32.       
    33.      private
    34.       
    35.      double
    36.       Round(
    37.      double
    38.       v,
    39.      int
    40.       x)
    41. {
    42.      bool
    43.       isNegative
    44.      =
    45.       
    46.      false
    47.      ;
    48.      //
    49.      如果是负数
    50.      
    51.       
    52.      if
    53.       (v
    54.      <
    55.       
    56.      0
    57.      )
    58. {
    59. isNegative
    60.      =
    61.       
    62.      true
    63.      ;
    64. v
    65.      =
    66.       
    67.      -
    68.      v;
    69. }
    70.      int
    71.       IValue
    72.      =
    73.       
    74.      1
    75.      ;
    76.      for
    77.       (
    78.      int
    79.       i
    80.      =
    81.       
    82.      1
    83.      ; i
    84.      <=
    85.       x; i
    86.      ++
    87.      )
    88. {
    89. IValue
    90.      =
    91.       IValue
    92.      *
    93.       
    94.      10
    95.      ;
    96. }
    97.      double
    98.       Int
    99.      =
    100.       Math.Round(v
    101.      *
    102.       IValue
    103.      +
    104.       
    105.      0.5
    106.      ,
    107.      0
    108.      );
    109. v
    110.      =
    111.       Int
    112.      /
    113.       IValue;
    114.      if
    115.       (isNegative)
    116. {
    117. v
    118.      =
    119.       
    120.      -
    121.      v;
    122. }
    123.      return
    124.       v;
    125. }
    126.    
    复制代码
      

    经过简单的测试,上面的函数能实现对数据的四舍五入法。
      
    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));
    回复

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-4-20 20:52 , Processed in 0.371202 second(s), 37 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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