如何判断数值能否在R的numeric类型中精确存储?
如何判断数值能否在R的numeric类型中精确存储
先给你明确R里的核心规则:numeric类型(本质是双精度浮点数)只能精确存储两类数值——整数(仅限-253到253之间的整数,超出这个范围的整数也会被舍入),以及分母为2的幂的分数(也就是可以写成k / 2^n的形式,k是整数,n是非负整数,n=0时就是整数)。其他所有数值都会被内部舍入到53位二进制精度。
那怎么判断一个给定数值属于哪一类呢?给你两种实用方法:
方法一:数学推导法
把数值转成最简分数形式,看分母的质因数是不是只有2:
- 如果是小数,先把它转换成最简分数
a/b(a、b是互质的整数,且b>0) - 检查b的所有质因数:如果只有2,那这个数就能被精确存储;要是还有其他质因数(比如5、3这类),就会被舍入。
举几个例子:
- 0.03125转成最简分数是
1/32,分母32=2^5,质因数只有2,所以能精确存储 - 0.1转成最简分数是
1/10,分母10=2×5,含有质因数5,所以无法精确存储
方法二:用R代码验证
1. 高精度打印验证
用sprintf输出足够多的小数位,如果输出结果末尾全是0,说明这个数是精确存储的;要是后面跟着一串非0的尾数位,就说明已经被舍入过了:
# 精确存储的例子 sprintf("%.60f", 1/32) #[1] "0.031250000000000000000000000000000000000000000000000000000000" # 非精确存储的例子 sprintf("%.60f", 0.1) #[1] "0.1000000000000000055511151231257827021181583404541015625000"
2. 转成最简分数验证
用MASS包的fractions函数把数值转成最简分数,直接看分母是不是2的幂:
library(MASS) # 精确情况 fractions(0.03125) # 输出 1/32,分母32是2的5次方,符合要求 # 非精确情况 fractions(0.1) # 输出 1/10,分母10包含质因数5,不符合要求
3. 整数范围验证
对于整数,要确认它在-253到253之间,超出这个范围的整数无法被精确存储:
# 这个整数在范围内,能精确表示 2^53 == 2^53 #[1] TRUE # 超出范围的整数会被舍入,导致相等 2^53 == 2^53 + 1 #[1] TRUE
内容的提问来源于stack exchange,提问作者989
相关产品推荐
相关产品推荐

