我想我会疯了。 “反击”和“间隔”都是双打。这发生在加速度计上:didAccelerate,间隔为(.01)。 “计数器”最终应增加到“间隔”。由于某种原因,我不能得到这个“如果”响。
我忽略了什么吗?
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) );
不要将双打或花车与平等进行比较 - 它们在您正在检查的有效数字的数量上可能看起来相同但计算机看得更多。
为此,Foundation Framework为不同类型提供“epsilon”值,例如“float”和“double”。如果两个数字之间的距离小于epsilon,则可以假设这两个数字相等。
在您的情况下,您将使用它如下:
- (BOOL)firstDouble:(double)first isEqualTo:(double)second {
if(fabs(first - second) < DBL_EPSILON)
return YES;
else
return NO;
}
或者在Swift 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
Interesting discussion of Unit in Last Place (ULP) and usage in Swift
在你的else
块中,你没有将0.01
添加到counter,因为那不是可表示的双精度值。您实际上是在添加值:
0.01000000000000000020816681711721685132943093776702880859375
不出所料,当你反复将这个值添加到自身时,你永远不会完全得到0.5
。
两个选择:更好的是用if
替换(counter >= interval)
条件。或者,你可以使用两个小的幂来增加,而不是像0.0078125
那样无法表示的东西。