管理浮点精度
Managing floating point accuracy
我正在为问题而苦苦挣扎。浮点精度,找不到解决方案。
这是一个简短的例子:
aa<-c(99.93029, 0.0697122)
aa
[1] 99.9302900 0.0697122
aa[1]
99.93029
print(aa[1],digits=20)
99.930289999999999
看起来,在存储向量后,R 将数字转换为内部表示略有不同的东西(是的,我已经阅读了 "R inferno" 的圆圈 1 和类似的 material) .
如何强制 R 在不进行修改的情况下准确地存储输入值 "as is"?
在我的例子中,我的问题是这些值的处理方式使得小错误很快增长:
aa[2]/(100-aa[1])*100
[1] 100.0032 ## Should be 100, of course !
print(aa[2]/(100-aa[1])*100,digits=20)
[1] 100.00315593171625
所以我需要找到一种方法来使我的规范化正确。
谢谢
PS- 这个网站和其他地方有很多问题,讨论明显的精度损失问题,即数字显示不正确(但存储正确)。在这里,例如:
How to stop read.table from rounding numbers with different degrees of precision in R?
这是一个明显的问题,因为数字存储不正确(但显示正确)。
(R 版本 3.2.1 (2015-06-18), win 7 x64)
我猜你误会了这里。这与 R 存储正确值的情况相同,但该值根据显示时选择的选项值相应地显示。
例如:
# the output of below will be:
> print(99.930289999999999,digits=20)
[1] 99.930289999999999395
但是
# the output of:
> print(1,digits=20)
[1] 1
还有
> print(1.1,digits=20)
[1] 1.1000000000000000888
浮点精度总是会引起很多混淆。要记住的关键思想是:当你使用双精度数时,没有办法存储每个实数 "as is" 或 "exactly right" —— 你能存储的最好的是最接近的可用近似值。因此,当您输入(用 R 或任何其他现代语言)类似 x = 99.93029
的内容时,您将得到由 99.930289999999999
.
表示的数字
现在,当您期望 a + b
为 "exactly 100" 时,您的用语就不准确了。你能得到的最好是“小数点后最多N位100”,希望N足够大。在你的情况下,说 99.9302900 + 0.0697122
是 100 是正确的,精确度为 5 个小数点 。自然地,通过将该等式乘以 10^k,您将失去额外的 k 位精度。
所以,这里有两个解决方案:
一个。要获得更高的输出精度,请提供更高的输入精度。
bb <- c(99.93029, 0.06971)
print(bb[2]/(100-bb[1])*100, digits = 20)
[1] 99.999999999999119
b。如果双精度不够(可能发生在复杂的算法中),请使用提供额外数字精度操作的包。例如,包 gmp
.
除了以前的答案,我认为关于这个主题的一个很好的讲座是
R 地狱,来自 P.Burns
我正在为问题而苦苦挣扎。浮点精度,找不到解决方案。
这是一个简短的例子:
aa<-c(99.93029, 0.0697122)
aa
[1] 99.9302900 0.0697122
aa[1]
99.93029
print(aa[1],digits=20)
99.930289999999999
看起来,在存储向量后,R 将数字转换为内部表示略有不同的东西(是的,我已经阅读了 "R inferno" 的圆圈 1 和类似的 material) .
如何强制 R 在不进行修改的情况下准确地存储输入值 "as is"?
在我的例子中,我的问题是这些值的处理方式使得小错误很快增长:
aa[2]/(100-aa[1])*100
[1] 100.0032 ## Should be 100, of course !
print(aa[2]/(100-aa[1])*100,digits=20)
[1] 100.00315593171625
所以我需要找到一种方法来使我的规范化正确。
谢谢
PS- 这个网站和其他地方有很多问题,讨论明显的精度损失问题,即数字显示不正确(但存储正确)。在这里,例如: How to stop read.table from rounding numbers with different degrees of precision in R? 这是一个明显的问题,因为数字存储不正确(但显示正确)。
(R 版本 3.2.1 (2015-06-18), win 7 x64)
我猜你误会了这里。这与 R 存储正确值的情况相同,但该值根据显示时选择的选项值相应地显示。 例如:
# the output of below will be:
> print(99.930289999999999,digits=20)
[1] 99.930289999999999395
但是
# the output of:
> print(1,digits=20)
[1] 1
还有
> print(1.1,digits=20)
[1] 1.1000000000000000888
浮点精度总是会引起很多混淆。要记住的关键思想是:当你使用双精度数时,没有办法存储每个实数 "as is" 或 "exactly right" —— 你能存储的最好的是最接近的可用近似值。因此,当您输入(用 R 或任何其他现代语言)类似 x = 99.93029
的内容时,您将得到由 99.930289999999999
.
现在,当您期望 a + b
为 "exactly 100" 时,您的用语就不准确了。你能得到的最好是“小数点后最多N位100”,希望N足够大。在你的情况下,说 99.9302900 + 0.0697122
是 100 是正确的,精确度为 5 个小数点 。自然地,通过将该等式乘以 10^k,您将失去额外的 k 位精度。
所以,这里有两个解决方案:
一个。要获得更高的输出精度,请提供更高的输入精度。
bb <- c(99.93029, 0.06971)
print(bb[2]/(100-bb[1])*100, digits = 20)
[1] 99.999999999999119
b。如果双精度不够(可能发生在复杂的算法中),请使用提供额外数字精度操作的包。例如,包 gmp
.
除了以前的答案,我认为关于这个主题的一个很好的讲座是
R 地狱,来自 P.Burns