0

我正在尝试测试一个数字是否可以被另一个完全整除(无余数)。如果我将它与 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");     
}

我究竟做错了什么?

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

4

3 回答 3

3

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

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

如果您要编写任何严肃的数字代码,最好阅读Goldberg 关于浮点运算的论文。

于 2013-04-09T12:01:23.123 回答
1

如果您想在 0.1 秒后重复使用 NSTimer 执行任务:

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

要停止计时器调用:

[timer invalidate];
于 2013-04-09T12:18:33.740 回答
0

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

于 2013-04-14T15:33:40.233 回答