4 Stimmen

NSDate und Double-Präzisionsproblem

Hier ist der Code

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);

die Ausgabe ist

Interval: 32,456000 32,456000 32455,999970 32456,000000

Warum gibt NSDate den Wert zurück, der einige Genauigkeiten verliert?

7voto

Yuji Punkte 33823

Das liegt nicht am Problem von NSDate selbst. Es liegt in der Natur der Gleitkommazahlen selbst. Ich glaube, dass NSDate sein Datum vom OS X-Epoche (2001) behält, nicht von der UNIX-Epoche (1970). Lassen Sie die Differenz zwischen den beiden Epochen x sein.

Dann passiert Folgendes:

NSDate* d = [NSDate dateWithTimeIntervalSince1970:32.4560];
// zu diesem Zeitpunkt behält d 32.4560 + x
double ti = [d timeIntervalSince1970];
// ti ist dann (32.4560+x)-x

Das Gleitkommazahl hat jedoch keine unendliche Genauigkeit. So kann +x und dann -x einen leichten Fehler in der Berechnung einführen.

Lesen Sie für mehr z.B. diesen Wikipedia-Artikel.

Wenn Sie die OS X-Epoche verwenden, erhalten Sie, was Sie naiv erwarten:

NSDate* d = [NSDate dateWithTimeIntervalSinceReferenceDate:32.4560];
// zu diesem Zeitpunkt behält d 32.4560 + 0
double ti = [d timeIntervalSinceReferenceDate];
// ti ist dann (32.4560+0)-0, was selbst in der Gleitkommawelt 32.4560 ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X