compat: fix jrand48()
According to the manpage, jrand48()
must return a signed long integer
uniformly distributed over the interval [-2³¹, 2³¹).
The old implementation first computed iterate48()
, which returns a
positive 48-bit integer (as uint64_t
, then cast to int64_t
). Once
right-shifted by 16 bits, the result is guaranteed to be a 32-bit
positive integer as int64_t
.
It is then (implicitly) cast to long
to match the return type.
When the 32th bit is 0 (i.e. the value fits in 31-bit), then everything is ok. However, when the 32nd bit is 1, then there are two cases (which are both incorrect):
- if the
long
type is 32-bit on the platform, then conversion fromint64_t
tolong
is undefined; - if the
long
type is more than 32-bit, then the resulting value will be a positive integer in the interval [0, 2³²), whereasjrand48()
must return a value in the interval [-2³¹, 2³¹).