2010-12-16 19 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は、UNIXエポック(1970年)ではなくOS Xエポック(2001年)からの日付を保持していると私は信じている。 2つのエポックの差を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のエポックを知りませんでしたがたぶん私は用語「OpenStepのエポックを使用していたはずです2001年 – teerapap

+0

です代わりに。 http://docs.sun.com/app/docs/doc/802-2112/6i63mn64s?l=ja&a=view#05.Classes-81 OpenStepの仕様は2001年以前のものだと私は信じています。将来の参照日付。 – Yuji