bit shifting

Ken Dickey kend at apple.com
Mon Apr 13 21:30:27 UTC 1998


FYI, this is what Common Lisp does:

[see _Common Lisp the Language, 2nd Edition_
  
http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/html/cltl/clm
/clm.html
]


(ash <integer> <count>)

This function shifts <integer> arithmetically left by <count> bit 
positions if <count> is positive, or right by -<count> bit positions if 
<count> is negative. **The sign of the result is always the same as the 
sign of integer. **

Mathematically speaking, this operation performs the computation 
     floor( <integer> *  2 ^<count> )

Logically, this moves all of the bits in integer to the left, adding 
zero-bits at the bottom, or moves them to the right, discarding bits. (In 
this context the question of what gets shifted in on the left is 
irrelevant; integers, viewed as strings of bits, are ``half-infinite,'' 
that is, conceptually extend infinitely far to the left.)

 For example: 
  (logbitp j (ash n k)) == (and (>= j k) (logbitp (- j k) n))


=========== ...


The logical operations in this section require integers as arguments; it 
is an error to supply a non-integer as an argument. The functions all 
treat integers as if they were represented in two's-complement notation. 


Implementation note: Internally, of course, an implementation of Common 
Lisp may or may not use a two's-complement representation. All that is 
necessary is that the logical operations perform calculations so as to 
give this appearance to the user. 


The logical operations provide a convenient way to represent an infinite 
vector of bits. Let such a conceptual vector be indexed by the 
non-negative integers. Then bit j is assigned a ``weight'' 2^j. Assume 
that only a finite number of bits are 1's or only a finite number of bits 
are 0's. A vector with only a finite number of one-bits is represented as 
the sum of the weights of the one-bits, a positive integer. A vector with 
only a finite number of zero-bits is represented as -1 minus the sum of 
the weights of the zero-bits, a negative integer. 

This method of using integers to represent bit-vectors can in turn be 
used to represent sets. Suppose that some (possibly countably infinite) 
universe of discourse for sets is mapped into the non-negative integers. 
Then a set can be represented as a bit vector; an element is in the set 
if the bit whose index corresponds to that element is a one-bit. In this 
way all finite sets can be represented (by positive integers), as well as 
all sets whose complements are finite (by negative integers). The 
functions logior, logand, and logxor defined below then compute the 
union, intersection, and symmetric difference operations on sets 
represented in this way. 

==========

Cheers,
-Ken
===========

>>Hi,
>>has anybody else discovered that bit shifting of negative numbers is
>>broken? Although the comment in Integer>>bitShift: says that it shifts
>>the two's complement, it's actually doing one's complement shifting,
>>i.e.
>>	(-1 bitShift: 1) = -2
>>which is plain wrong. Unfortunately, if I correct the
>>SmallInteger>>bitShift: method, LargeInteger division breaks. And I
>>don't want to mess with Integer>>digitDiv:neg: !


>>HOWEVER, before doing that, there is a theoretical issue that I would want 
>>to hear some agreement on from the NAG (numerics affinity group -- you 
>>know hwo you are ;-).  
....





More information about the Squeak-dev mailing list