2011-01-19 69 views
7

我想我会疯了。 “counter”和“interval”都是双打。这发生在加速度计上:以(.01)为间隔进行加速度测量。 “计数器”最终应该增加到“间隔”。出于某种原因,我不能得到这个“如果”以响应。iphone/Objective C - 比较双打不工作

我可以俯视吗?

double interval = .5; 
if(counter == interval){ //should eventually be .50000 == .50000 
    NSLog(@"Hit!"); 
    [self playSound]; 
    counter = 0; 
}else{ 
    counter += .01; 
} 
NSLog(@"%f, %f, %d",counter,interval,(counter == interval)); 
+1

[Objective-c \ [SOLVED \]中浮点问题的可能的重复](0123)[编辑] – Seth 2011-01-19 07:15:24

+0

是的,原来就是这样。虽然它似乎是相反的问题,但我使用了浮点类型并且工作正常。谢谢塞斯 – azeven 2011-01-19 07:23:39

回答

2

在你else块,您不添加0.01对抗,因为那是不是表示的双精度值。你实际上是添加值:

0.01000000000000000020816681711721685132943093776702880859375 

毫不奇怪,当你反复地将此值添加到自己,你永远不会得到0.5准确。

两种选择:最好是用(counter >= interval)代替if条件。或者,您可以使用两个较小的幂来代替无法表示的东西,如0.0078125

17

永远不要比较双打或浮动平等 - 他们可能看起来相同的重要数字,你正在检查,但电脑看到更多。

为此,Foundation Framework为不同类型(例如“float”和“double”)提供“epsilon”值。如果两个数字之间的距离小于ε,则可以假设这两个数字相等。

在你的情况,你会用它如下:

- (BOOL)firstDouble:(double)first isEqualTo:(double)second { 
    if(fabs(first - second) < DBL_EPSILON) 
     return YES; 
    else 
     return NO; 
} 

还是在斯威夫特4:

func doublesAreEqual(first: Double, second: Double) -> Bool { 
    if fabs(first - second) < .ulpOfOne { 
     return true 
    } 
    return false 
} 

两个非常有用的链接:

What Every Computer Scientist Should Know About Floating-Point Arithmetic

Friday Q&A 2011-01-04: Practical Floating Point