2010-12-16 2 views
4

Вот кодNSDate и двойной точности проблема

NSDate* d = [NSDate dateWithTimeIntervalSince1970:32.4560]; 
double ti = [d timeIntervalSince1970]; 
NSLog(@"Interval: %f %f %f %f",ti,32.4560,ti*1000.0,32.4560*1000.0); 

выход

Интервал: 32,456000 32,456000 32455,999970 32456,000000

Почему NSDate возвращают значение, которое теряет некоторые Precisions?

ответ

7

Это не проблема NSDate. Это характер самих чисел с плавающей запятой. Я считаю, что NSDate сохраняет свою дату с эпохи OS X (2001), а не эпохи UNIX (1970). Пусть разность двух эпох равна x.

Тогда что это происходит:

NSDate* d = [NSDate dateWithTimeIntervalSince1970:32.4560]; 
// at this point, d keeps 32.4560 + x 
double ti = [d timeIntervalSince1970]; 
// ti is then (32.4560+x)-x 

Однако с плавающей точкой не имеют бесконечную точность. Итак, +x, а затем -x может внести небольшую ошибку в расчет.

Для получения дополнительной информации см. this Wikipedia article.

Если вы используете OS X эпоху, вы получите то, что вы наивно ожидать:

NSDate* d = [NSDate dateWithTimeIntervalSinceReferenceDate:32.4560]; 
// at this point, d keeps 32.4560 + 0 
double ti = [d timeIntervalSinceReferenceDate]; 
// ti is then (32.4560+0)-0, which is 32.4560 even in the floating point world. 
+0

Спасибо, я не знаю OSX эпохи 2001. – teerapap 2010-12-16 06:38:41

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