NSDate and double precision problem
-
10-10-2019 - |
Question
Here is the 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);
the output is
Interval: 32.456000 32.456000 32455.999970 32456.000000
Why NSDate return the value which lose some precisions?
Solution
That's not the problem of NSDate
itself. It's in the nature of the floating point numbers themselves. I believe NSDate
keeps its date from the OS X epoch(2001), not the UNIX epoch (1970). Let the difference in the two epochs be x.
Then what happens is this:
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
However, the floating point doesn't have infinite precision. So, +x
and then -x
can introduce slight error in the calculation.
For more, read e.g. this Wikipedia article.
If you use the OS X epoch, you get what you naively expect:
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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow