module Data.Bits

Malcolm Wallace Malcolm.Wallace@cs.york.ac.uk
Mon, 9 Sep 2002 15:53:41 +0100


Alastair Reid <alastair@reid-consulting-uk.ltd.uk> writes:

> > The FFI spec says that the operations called 'shift' and 'rotate',
> > shift and rotate their argument to the right.  However, the GHC
> > implementation in CVS shifts and rotates to the left, and is
> > documented to do so.
> 
> They shift to the left as in C, etc.

Errm, but in C there is no unified shift operator.  You have <<
for left shift and and >> for right shift, and a negative shift
is undefined.

> This makes the specification come out nice and clean - you're
> multiplying the number by 2^n instead of 2^{-n}.

Errm, but then right shift comes out as dividing by 2^{-n}, instead
of 2^n.  For a unified shift operation, I don't think there is any
good reason to prefer one direction over the other, since there is
no precedent in another language (AFAIK).

However, while I'm on the subject, I'd like to request that the operations

    shiftL, shiftR,    -- :: a -> Int -> a
    rotateL, rotateR,  -- :: a -> Int -> a

should become members of the class, with new default implementations

    x `shift`   i  | i<0  = x `shiftL` i
                   | i==0 = x
                   | i>0  = x `shiftR` i
    x `rotate`  i  | i<0  = x `rotateL` i
                   | i==0 = x
                   | i>0  = x `rotateR` i

    x `shiftL`  i  = x `shift`  (-i)
    x `shiftR`  i  = x `shift`  i
    x `rotateL` i  = x `rotate` (-i)
    x `rotateR` i  = x `rotate` i

(or with the directions the other way round if you insist.)

As I already noted, languages such as C provide only left and right
shift (with no unified variant), and it would be nice to have the
ability to override the default implementations of shiftL etc for
specific types where we can call C directly.  At the moment, a right
shift turns into two negations in Haskell followed by the primitive
call, and I'd like to squeeze the extra efficiency in if I can.

Regards,
    Malcolm