如何在R语言全局选项中设置15位舍入精度,无需逐次调用round函数?
首先得跟你说清楚,你碰到的这个问题其实是浮点数存储的固有特性——像0.1这种十进制小数,在二进制里是无限循环的,所以R里存的0.1本身就是个近似值,乘6之后得到的结果和直接写的0.6(同样是近似值)之间会有极小的差异,这就是为啥x*y==0.6会返回FALSE。
针对你想要**全局设置15位精度舍入、不用每次手动调用round()**的需求,给你几个可行的方案:
方案1:用all.equal()代替==做比较(首推)
这是R里处理浮点数比较的标准操作,不用改计算逻辑,只需要换个比较方式就行。all.equal()会自动考虑双精度浮点数的合理误差范围,默认的容忍度刚好适配15-17位有效数字的精度:
x <- 0.1 y <- 6 all.equal(x*y, 0.6) # 返回 TRUE
要是你需要更严格的精度控制,还可以通过tolerance参数自定义,比如tolerance = 1e-15来精准匹配15位精度。
方案2:自定义算术运算符实现自动舍入
如果你确实需要让所有乘法运算都自动舍入到15位,可以重新定义乘法运算符,但要注意:这会影响全局所有的乘法操作,可能带来意想不到的副作用,用之前一定要谨慎:
# 先把原始的乘法运算符存起来 `%old*%` <- `*` # 重新定义乘法,自动舍入到15位有效数字 `*` <- function(a, b) round(`%old*%`(a, b), digits = 15) # 测试效果 x <- 0.1 y <- 6 x*y == 0.6 # 现在返回 TRUE x*y - 0.6 # 返回 0
之后要是想恢复原始的乘法运算,只需要运行rm("*")就行。
方案3:设置显示精度(注意:不改变计算精度)
options(digits = 15)能让R在输出结果时显示15位有效数字,但这不会改变实际的计算精度——底层的浮点数还是原来的近似值,只是显示的时候被舍入了。所以用==比较的时候仍然会得到FALSE,这个选项更适合调整输出的美观度,解决不了你的比较问题:
options(digits = 15) x*y # 显示 0.6 x*y == 0.6 # 依旧返回 FALSE
最后提一句,浮点数精度问题几乎是所有编程语言都存在的,除非你用专门的高精度数值类型(比如R里的gmp或Rmpfr包),否则很难完全避免。优先用all.equal()做比较是最稳妥的方案,全局修改运算符一定要三思而后行哦。
内容的提问来源于stack exchange,提问作者Basel.D

