Subject: unnecessary bit shifting range limits

From: Zefram <[email-masked]>
Date: Thu, 12 Nov 2015 07:07:25 +0000

Not really outright bugs, but these responses are less than awesome:

$ guile -c '(write (logbit? (ash 1 100) 123))'
ERROR: Value out of range 0 to 18446744073709551615: 1267650600228229401496703205376
$ guile -c '(write (ash 0 (ash 1 100)))'
ERROR: Value out of range -9223372036854775808 to 9223372036854775807: 1267650600228229401496703205376
$ guile -c '(write (ash 123 (ash -1 100)))'
ERROR: Value out of range -9223372036854775808 to 9223372036854775807: -1267650600228229401496703205376

In all three cases, the theoretically-correct result of the expression
is not only representable but easily computed.  The functions could be
improved to avoid failing in these cases, by adding logic amounting to:

(define (better-logbit? b v)
  (if (>= b (integer-length v)) (< v 0) (logbit? b v)))

(define (better-ash v s)
  (cond
    ((= v 0) 0)
    ((<= s (- (integer-length v))) (if (< v 0) -1 0))
    (else (ash v s))))

-zefram