Subject: bug#32463: 27.0.50; (logior -1) => 4611686018427387903

From: Paul Eggert <[email-masked]>
Date: Sun, 19 Aug 2018 20:47:29 -0700

Richard Stallman wrote:
> What exactly is the problem with lsh and bignums?  Is it for negative
> numbers because there is no specific width?

Yes, that's it.

> One possible solution is to give lsh an optional third argument to
> specify the nominal width of the first argument.  The default could be
> the width of a fixnum on your platform.

Although we discussed something along those lines and could easily implement 
something, it's a bit trickier than it might sound at first, because of corner 
cases where the semantics are unclear. Here's one possible implementation (there 
are other approaches of course):

    (defun lsh (value count &optional width)
      (when (and (< value 0) (< count 0))
        (let ((lo (if width (ash 1 (1- width)) most-negative-fixnum)))
	 (when (< value lo)
	   (signal 'args-out-of-range (list value count width)))
	 (setq value (logand (ash value -1) (- -1 lo)))
	 (setq count (1+ count))))
      (ash value count))

I am skeptical whether the complexity of this extension is worth the effort to 
maintain and document. In a language with bignums, if you need a mask of bits 
you simply use a nonnegative integer, which means you can use ash without 
worrying about the corner cases that invariably afflict lsh.

> How does Scheme handle the issue?

Scheme does not have logical shifts, only arithmetic shifts. Logical shifts 
don't make that much sense once you have bignums.