2016-01-13 119 views
1

我有检查变量elapsedTime(double)是0.4的倍数的代码。即0.4,.0.8,1.2,1.6等等代码检查像这样:Swift%无法正确计算

let roundedInterval = Double(round(timeInterval*10)/10) //(this is 0.4) 
    let roundedActualElapsedTime = Double(round(actualElapsedTime*10)/10) 

     if roundedActualElapsedTime%roundedInterval == 0 { 

      print(“is a multiple of 0.4”) 
    } 
从我的结果输出0.4,0.8,1.6

然而,3.2被报道为倍数,因此它缺少的值。任何想法我可能在这里做错了吗?

注:roundedTimeInterval 0.4保持恒定,roundedActualElapsedTime增量在0.1秒即0.1,0.2,0.3,0.4 ...等

+0

什么是你的一个时间间隔,并actualElapsedTime例如? – aaisataev

+0

@aaisataev编辑了问题 – KexAri

+0

请参阅[浮点数学是否被破坏?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken):'0.4' *不能*完全表示为一个二进制浮点数。 –

回答

5

%运营商FloatDouble很可能将在斯威夫特3.0被删除,所以你不应该依赖它。讨论请参阅this swift-evolution thread

此外,您需要了解更多关于浮点数的知识。浮点数(在所有苹果平台上实现)只能表示m * 2 e的数字,其中m和e是整数(并且可能是负数)。只能以2的幂的整数倍(包括负值,如1/2,1/4,1/8等)精确地表示,而像0.1,0.2和0.3这样的数字不是任何功率的整数倍二。 (请注意,0.5是二的幂的整数倍:它是2 -1。)

因此,当你把round(timeInterval * 10)和除以10,你通常得到一个不精确的结果,并且通常你当不可t期望两个不精确结果的其余部分完全为零。

你可能想要做的是十分之一秒(十分之一秒)为整数的工作,从那时起你处理确切的数字:

let roundedTenths = Int(round(timeInterval*10)) 
let roundedElapsedTenths = Int(round(actualElapsedTime * 10)) 
if roundedElapsedTenths % roundedTenths == 0 { 
    print("is a multiple of 0.4") 
} 
+0

2的能力可以解释为什么0.5在工作作为一个时间间隔和0.4是不是那么。哇,疯狂的道具给你知道。现在修复。如果我想提高准确度,我可以使用* 100而不是* 10? – KexAri

+0

是的,你可以将两个数字乘以100。 –