bit shifting

William O. Dargel wDargel at shoshana.com
Wed Apr 15 04:17:38 UTC 1998


Hans-Martin Mosner wrote:

> Oops, I was having too much of that 1.23 stuff lately.
>
> Let me correct myself:
> (-1 bitShift: 1) = -2   is perfectly right.
> And it's what Squeak 1.31 computes.
>
> Squeak 1.23 got it wrong:
> (-1 bitShift: 1) = -1
> I was just too lazy to move my stuff from 1.23 to 1.31 (partially due
> to the fear that I would be unable to build the JIT VM under MPW) so I
> used that old stuff and fell over that bug which obviously has been
> fixed already.

Now I'm confused. I'm running Squeak 1.31 on Windows, and get:
    (-1 bitShift: 1) = -1
I would expect it to be -2. Was this changed between 1.23 and 1.31 but
maybe got missed on the Windows port? Or do you need to correct your
correction? ;-) The SmallInteger #bitShift: code when the primitive
fails is:
     self < 0 ifTrue: [^ -1 - (-1-self bitShift: arg)].
This just looks wrong to me.

I would expect that
    ((2 raisedTo: i) negated bitShift: 1) = (2 raisedTo: i+1) negated
would be true for all i >= 0.
Currently Squeak answers true only for i >= 31, and answers false for i
between: 0 and: 30. This can't be good.

> Note that I wholeheartedly agree with Ken Dickey that Common Lisp does
> it right, and that bit manipulation with negative numbers should be no
> problem at all.
> Especially there should not be such a thing as a logical right shift
> since that depends on the number of bits in whatever kind of register
> you're holding the number, and as a Smalltalk programmer I really
> don't care for the number of bits in a register... So right shifts
> should always be arithmetic "(self / (2 raisedTo: shiftCount)) floor"
> and left shifts are always multiplications by powers of two. Just like
> CL does it.
>
> Hans-Martin

I agree with you here (and Ken and Eliot). I would expect bit operations
on Integers to behave consistently, whether they are dealing with 4 bits
or 400. This means we need to treat values as though they had an
infinite number of 0 or 1 bits on the left. With that, #bitShift:,
#bitXor:, #bitOr:, #bitAnd: and even a #bitNot or #bitInvert could all
work in a completely consistent fashion.
And if one wanted to work with some particular number of bits (say 32),
you'd simply need to do a #bitAnd: with the appropriate mask to keep the
values in line.

-Bill

BTW: Anyone notice that the comment in Integer #>> is "left shift"? :-)

-------------------------------------------
Bill Dargel            wdargel at shoshana.com
Shoshana Technologies
100 West Joy Road, Ann Arbor, MI 48105  USA





More information about the Squeak-dev mailing list