2016-01-13 2 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

, что ваша TimeInterval и actualElapsedTime, например? – aaisataev

+0

@aaisataev Редактировать вопрос – KexAri

+0

См. [Является ли математика с плавающей запятой?] (Http://stackoverflow.com/questions/588004/is-floating-point-math-broken): '0,4' * не может быть представлен точно так же двоичное число с плавающей запятой. –

ответ

5

% оператор Float и Double, вероятно, будет удален в Swift 3.0, поэтому вы не должны полагаться на это. См. this swift-evolution thread для обсуждения.

Кроме того, вам нужно узнать больше о числах с плавающей запятой. Числа с плавающей запятой (как реализовано на всех платформах Apple) могут представлять только числа формы m * 2 e, где m и e - целые числа (и могут быть отрицательными). Только целые кратные мощности двух (включая отрицательные мощности, такие как 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. –

Смежные вопросы