Bit shifting limitations

John Meacham john at repetae.net
Sun Jul 13 19:29:44 UTC 2014


definitely.

I would much prefer to respecify shiftR and shiftL as masked in
nature, that is a much better state of affairs than calling error and
easier to arrange for arches that don't natively act that way.

Another advantage of logical and arithmetic shifts is that there would
be easier to get rid of the pesky 'Num' superclass as you wouldn't
need Word/Int trickery and depending on dubious fromIntegaral behavior
to get the one you want.

jhc actually has this behavior for the standard numeric types, it
makes a big difference in speed.

Data.Bits declaration
http://repetae.net/repos/jhc/lib/haskell-extras/Data/Bits.hs
Instances for Data
http://repetae.net/repos/jhc/lib/haskell-extras/Data/Bits.m4

The foreign primitive decls directly translate to the assembly/c--
opcodes which behave in the masking fashion you specified.

I am not entirely pleased with this as the Num superclass still
exists; users won't know to define both arithmetic and logical and
there isn't an easy way to create defaults for them while keeping
backwards compatibility. Once class aliases are fully integrated then
this will be straigtforward to solve in a backwards compatible manner.
It is still better than the alternative though.

     John

On Sun, Jul 13, 2014 at 11:36 AM, David Feuer <david.feuer at gmail.com> wrote:
> The current state of affairs is a bit unsatisfactory.
>
> 1. The biggest problem, as I see it, is that while we have shiftR and
> shiftL, which are documented as giving 0 or -1 when shifting too far, and we
> have unsafeShiftR and unsafeShiftL, which are likely to do whatever the CPU
> happens to do, we don't have anything guaranteed to shift using just the
> first five or six bits of the shift count, which is what Java specifies and
> what unsafeShiftR and unsafeShiftL *actually* do (at least on x86_64). I
> propose that we add these masked shifts to Data.Bits. The default
> implementations can look something like:
>
> shiftRMasked x count
>   | popCount (finiteBitSize x) != 1 = error "Masked shift only makes sense
> if the size is a power of 2."
>   | otherwise = x `unsafeShiftR` (count .&. (finiteBitSize x - 1))
>
> 2. It would be nice to specify what shiftR and shiftL are supposed to do
> when given negative shift counts. Is there a practical reason not to specify
> that?
>
> 3. I would like to add explicit arithmetic and logical shifts to Data.Bits.
> When fiddling bits, it's often easier to think about that distinction
> explicitly, rather than in terms of whether the type is signed or unsigned,
> and more convenient to have an explicit operation rather than casting
> around.
>
> David
>
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://www.haskell.org/mailman/listinfo/libraries
>



-- 
John Meacham - http://notanumber.net/


More information about the Libraries mailing list