2010-12-16 51 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返回的失去一些精度值?

回答

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

+0

也許我應該已經使用的術語「OpenStep的時代「而是。請參閱http://docs.sun.com/app/docs/doc/802-2112/6i63mn64s?l=en&a=view#05.Class-81我相信OpenStep規範是在2001年之前發佈的。它們非常雄心勃勃,可以設置將來的參考日期。 – Yuji 2010-12-16 08:34:39