如何检查带小数的双精度是否可被整除?

时间:2013-04-09 11:55:54

标签: ios objective-c math floating-point double

我正试图测试一个数字是否被另一个数字干净地整除(没有剩余部分)。如果我将它与int进行比较,它可以正常工作:

NSTimeInterval timeElapsed = // a double goes here

// round to 3 decimal points to avoid floating point weirdness
timeElapsed = [[NSString stringWithFormat:@"%.3f",timeElapsed] doubleValue];

然后

// This works correctly

if (fmod(timeElapsed, 1) == 0) {
           NSLog(@"is divisible");
 }

但如果我将它与小数进行比较,则会失败,只会间歇性地发射:

// This does NOT work correctly

if (fmod(timeElapsed, .1) == 0) {
            NSLog(@"is divisible");     
}

我做错了什么?

编辑:在阅读了下面的答案和好评之后,我得出结论,这整个方法都是一个坏主意。没有保证能够生成特定的时间间隔。最好只创建单独的计时器,而不是听一个“主”计时器。

3 个答案:

答案 0 :(得分:3)

通常,浮点数不能完全表示,因为您只有有限的位数来表示它们(通常为32或64位)。因此,您应该从不测试完全相等,而是在可接受的小容差范围内进行测试,例如

if (fabs(fmod(timeElapsed, .1)) < SOME_SMALL_VALUE) {
    NSLog(@"is divisible");     
}

如果你要编写任何严肃的数字代码,最好阅读Goldberg paper on floating point arithmetic

答案 1 :(得分:1)

如果要在0.1秒后执行任务,请反复使用NSTimer:

NSTimer *timer =  [NSTimer scheduledTimerWithTimeInterval:0.1
            target:self
            selector:@selector(yourMethod:)
            userInfo:nil
            repeats:YES];

停止计时器调用:

[timer invalidate];

答案 2 :(得分:0)

这是一个糟糕的方法。浮点数不可信任。为每个元素提供自己的计时器,这样您就不必听特定的数字了。