我知道浮点数很奇怪,但是我之前从未遇到过这个确切的问题。我在R中有一个数字向量。我看到有多少个比零大的数字,我取其平均值即可使比重大于零。我将数字四舍五入后分配给一个对象。当我去粘贴它时,数字又回来了。我会dput
向量,但是这样做太长了,但这是head
和str
:
> head(x)
[1] 0.1616631 0.2117250 0.1782197 0.1791657 0.2067048 0.2042075
> str(x)
num [1:4000] 0.162 0.212 0.178 0.179 0.207 ...
现在这是我遇到的问题:
> y <- round(mean(x > 0) * 100, 1)
> y
[1] 99.7
> str(y)
num 99.7
> paste(100 - y, "is the inverse")
[1] "0.299999999999997 is the inverse"
但是如果我不从100中减去,它的行为就不会一样:
> paste(y, "is it pasted")
[1] "99.7 is it pasted"
我知道我可以将round
直接放在paste
命令中或使用sprintf
,而且我知道R中的浮点数表示方式,但是我特别想知道< em>为什么发生在前者而不是后者?我也无法得到可复制的示例,因为我也无法使随机生成的向量以相同的方式工作。
答案 0 :(得分:4)
存在舍入错误,但是在这种情况下R不能很好地处理它。
R中任何浮点数的表示都以double
表示,这意味着53位精度,大约16位数字。这也适用于99.7
,您可以看到它的分解位置:
print(99.7, digits=16) # works fine
print(99.7, digits=17) # Adds a 3 at the end on my platform
这将永远是一个限制,在印刷版中(在文档中)指定该警告时会警告您。
但是,当您进行计算时,任何舍入误差仍然是绝对的,这意味着您期望的.3值具有绝对误差,该误差同样大,但相对而言 大300倍。因此,它“失败”了低有效数字:
print(100-99.7, digits=14) # works fine
print(100-99.7, digits=15) # Allready rounding error at digits=15
现在paste
将任何数字传递给函数as.character
,该函数(不幸的是,在这种情况下)不会查看您已设置的任何选项,它始终使用15个有效数字的默认值。
要解决此问题,您可以使用format
指定所需的位数:
paste(format(100 - y, digits=14), "is the inverse")