为什么R粘贴的小数位数比四舍五入的位数多,但有时仅粘贴?

时间:2018-12-13 20:18:32

标签: r floating-point

我知道浮点数很奇怪,但是我之前从未遇到过这个确切的问题。我在R中有一个数字向量。我看到有多少个比零大的数字,我取其平均值即可使比重大于零。我将数字四舍五入后分配给一个对象。当我去粘贴它时,数字又回来了。我会dput向量,但是这样做太长了,但这是headstr

> 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>为什么发生在前者而不是后者?我也无法得到可复制的示例,因为我也无法使随机生成的向量以相同的方式工作。

1 个答案:

答案 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")