On Sun, 2022-03-27 at 17:04 +0200, Jean Abou Samra wrote: > Ugh, ugh, ugh. > > \version "2.23.7" > > #(display (strftime "%c" (localtime -499092417))) > #(newline) > #(display (strftime "%c" (localtime (+ -499092417 (expt 2 31))))) > > => > > Tue Mar 9 12:13:03 1954 > > Sun Mar 27 16:27:11 2022 > > > So this is an overflow error. At least on the MingW we use, > the size of long is apparently 32 bits, which does not suffice > for time purposes. Jonas, what do you think?
Okay, let me try to sort this out. First off, yes longs are 32 bits even on 64 bit Windows. Nothing to do with with MinGW though, that's just the LLP64 ABI chosen by Microsoft (ie, long long and pointer are 64 bits). However, the timestamp discussed above is 1648391231 which still fits nicely into signed 32 bits, where the maximum (positive) value is 2147483647 (ie 2 ** 31 - 1). In fact signed 32 bit numbers will serve us another 16 years before overflowing, the Y2038 issue. Furthermore, the addition of (expt 2 31) above is wrong, should be (expt 2 32) because it's the 33rd bit that cannot be represented. Let me demonstrate at 8 bits where numbers are more easier to look at: A signed number with 8 bits can range from -128 to +127. If you overflow on the positive side, +128 is congruent to -128. Similarly if you clamp 256 = 0x100, you get a 0 at 8 bits. In both cases, the difference is 256 = 2 ** 8. So what is happening here is that Guile stores immediate integers by converting to a 64 bit number and then shifting two bits to the left. In our case, this transforms 1648391231 = 0x6240743F into 0x18901D0FC where the first bit is indeed too large for 32 bit. The error happens when extracting the integer from this representation where the code first converts to 32-bit, getting us a 0x8901D0FC and losing the first bit, and then shifting two bits to the right. Due to sign extension, the result is 0xE240743F = -499092417. I think I see where to fix this in Guile 2.2, let me try. (FWIW the code appears to be reworked in Guile 3.0 and looks correct with respect to this issue, but we cannot use it because it's too different...) Jonas
signature.asc
Description: This is a digitally signed message part