lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: LilyPond 2.23.7 released


From: Jonas Hahnfeld
Subject: Re: LilyPond 2.23.7 released
Date: Sun, 27 Mar 2022 21:39:22 +0200
User-agent: Evolution 3.42.4

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

Attachment: signature.asc
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]