暂无说说

自定义函数,解决R四舍五入问题

R jiajun 2年前 (2016-04-27) 48次浏览 0个评论 扫描二维码

对于“四舍五入”的概念,相信大家都熟悉,因为小学三四年级就已经接触过了,但对于银行家算法,也许有不少人比较生疏。此前,曾经听说过银行家算法,也知道算法“四舍六入五考虑”的具体实现方法,那就是:五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。银行家舍入是 IEEE 规定的小数舍入标准之一,也是 IEEE 目前规定中最优秀的舍入方法,因此所有符合 IEEE 标准的语言都应该实现这种算法。R的 round 函数使用 IEEE 标准,也就自然而然地使用银行家算法,所以得出的结果跟“四舍五入”的结果会有差异。当业务要用到“四舍五入”时,怎么处理呢?既然 round 不能实现“四舍五入”,那就抛开 round,自己定义一个“myround”方法,凑活着用用。
问题举例,考虑下面语句输出结果:

可以发现,当 0.5 前面的值为奇数的时候,则向前进入,当前面的值为偶数的时候,则把 0.5 舍去。跟传统的“四舍五入”存在差别。下面简单介绍自定义函数 myround 的实现。

算法 1:假设要四舍五入的数为 x,保留的小数位数为 n

①获取 x 的符号,记为 vorz

②计算

③对 z 向下截断,并把结果赋值给 z

④计算

⑤返回

对应的R代码如下:

myround = function(x, n){
    vorz = sign(x)
    z = abs(x) * 10^n
    z = z + 0.5
    z = trunc(z)
    z = z/10^n
    return(z * vorz)
}


①算法 2:

①计算\(10^{n}x+0.5\)

\(z\)对进行向下取整

③计算\(z=\dfrac {z}{10^{n}}\)

④返回\(z\)


myround = function(x, n){
    z = x * 10^n
    z = z + 0.5
    z = floor(z)
    z = z/10^n
    return (z)
}


再次测试一开始的代码:

四舍五入完成。

代码改进:考虑到下面的问题,当用 myround 对 4.5 四舍五入时,第二个参数忘记写,会出现下面报错,为了避免这种情况发生,给 n 设置默认值 0,即默认情况下是保留整数位。

改进后代码如下:

myround = function(x, n=0){
    vorz = sign(x)
    z = abs(x) * 10^n
    z = z + 0.5
    z = trunc(z)
    z = z/10^n
    return(z * vorz)
}

myround = function(x, n=0){
    z = x * 10^n
    z = z + 0.5
    z = floor(z)
    z = z/10^n
    return (z)
}

 


mathslib , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:自定义函数,解决 R 四舍五入问题
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址