Pondering 2038
Pondering 2038
Posted Aug 19, 2013 1:48 UTC (Mon) by ras (subscriber, #33059)In reply to: Pondering 2038 by tmattox
Parent article: Pondering 2038
The problem is the 53 bit precision provided a IEEE 754 mantissa provided is nowhere near enough. IEEE 754 does define a quadruple precision with 113 bits which is enough, but no one implements it. In fact not everyone implements IEEE floats, and IIRC the kernel doesn't use or depend floats at all. That probably rules out floats completely. Still it would be very nice format for higher level languages like say Python. Double double (a 128 floating point format that emulates 128 bit using 2 doubles) is more than fast enough for interpreted languages.
IMHO the right solution to this is a new timeval like this:
struct timeval64 {
int64_t tv_sec; // Time in seconds since say 1/1/0001.
uint32_t tv_frac; // 1 / 2^32 second
}
Storing the fractional part as 1 / 2^32 has a number of advantages over microseconds. Although it doesn't seem "natural", turns out not many people use microseconds directly either so they have to convert it. As soon as you have to do that the code becomes identical. Eg, to convert to milliseconds:
milliseconds = tv_usec / ((1000*1000) / 1000)
milliseconds = tv_frac / ((1 << 32) / 1000)
milliseconds = (int64_t)tv_frac * 1000 >> 32 // Also works
The second form above is a better choice on architectures where divide is slow.
Storing stuff as 1 / 2^32 gives the full precision for the bits available, yielding a resolution of around 4GHz which happens to neatly fit with where CPU frequencies have plateaued.
Converting it to a 128 bit time becomes just a shift and add, mainly because this is just a 96 bit time in disguise.
Moving the epoc to 1/1/0001 solves a problem I continually get bitten by: times less that 1970 blowing up. Given 64 bits gives us 292e9 years, it could equally well be 13,000,000,000 BC which is the one true epoc (the big bang), however I am not sure what we do for calendars back then.
In comparison storing times in nanoseconds in a int64_t looks like a 1/2 baked solution. As others have observed here, it only delays the problem for a couple of hundred years, doesn't provide enough precision and doesn't address the 1/1/1970 wart.