2011-07-29 44 views
4

可能重复:
Why are these numbers not equal?R中的浮点问题?

的以下表达式,计算结果为0.1,被认为是大于0.1。

> round(1740/600,0) - 1740/600 
[1] 0.1 
> (round(1740/600,0) - 1740/600) <= 0.1 
[1] FALSE //???!!??? 
> (round(1740/600,0) - 1740/600) <= 0.1000000000000000000000000000000000000001 
[1] TRUE 

思考这个问题可能是由于四舍五入的原因我想这同样的结果:

> 3 - 2.9 
[1] 0.1 
> (3 - 2.9) <=0.1 
[1] FALSE 

那么,是什么给和我怎么解决它没有捏造截止?

+7

阅读本FAQ:http://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are- equal_003f –

+0

[R Inferno](http://www.burns-stat.com/pages/Tutor/R_inferno.pdf)也是一个很好的阅读。 – Aaron

回答

10

Floating-Point Guide

为什么我的数字,像0.1 + 0.2加起来一个漂亮的圆0.3, 而是我得到一个怪异的结果像0.30000000000000004?

由于内部计算机使用格式(二进制浮点数) ,因此无法准确表示数字,如0.1,0.2或0.3。

当代码被编译或解释时,您的“0.1”已经被 舍入到该格式的最接近的数字,即使在计算发生之前,这也会导致一个小的舍入误差。

我该怎么做才能避免这个问题?

这取决于你在做什么样的计算。

  • 如果你真的需要你的结果加起来,特别是当你使用金钱工作时:使用特殊的十进制数据类型。
  • 如果您只是 不想看到所有这些额外的小数位数:只需在显示时将您的 结果格式化为固定的小数位数。
  • 如果您没有可用的小数数据类型,则可以使用带整数的 (例如,完全以美分计算金钱。但这 是更多的工作,并有一些缺点。
+0

所以如果我需要做精确的比较,我应该将小数点移到右边并截断,以便比较整数? – dnagirl

+0

@dnagirl:或者使用epsilon值进行比较(详见链接)。但无论如何,当你处理不精确的数据时,放弃“精确比较”的想法。真正的问题是你的数据来自哪里 - 如果你的输入已经是近似的,那么担心这样的人为角落案例是毫无意义的。 –

+0

在这种情况下,我试图通过测量的时间接近一组周期性事件来对时间轨迹数据进行分组。我的数据每秒测量一次。事件每隔10分钟发生一次。我想在每场比赛的任何一方得到60秒。 – dnagirl

12

存在R功能,可以自动采取明智的做法“平等问题”:

> (3 - 2.9) <=0.1 
#[1] FALSE 

> all.equal((3 - 2.9) , 0.1) 
#[1] TRUE 

它使用的r最小的正浮点数作为其默认的阈值的平方根,因此处理乘法和除法传播错误。结束大约1e-08