Bit shifts

Jose E. Marchesi jemarch@gnu.org
Wed Feb 4 09:43:37 GMT 2026


Hello people.


As James already noticed, the existing implementation of the standard
bit shifting operators SHR and SHL just uses the same C semantics, and
also it is broken.

The Revised Report defines the following semantics for the operators.
Note that below I use the notation c[N] to mean the Nth bit in c, but we
know bits values cannot be sliced like that.

    op SHL = (bits a, int b) bits:
       if ABS b <= bits_width
       then bits c := a;
            to ABS b
            do if b > 0
               then for i from 2 to bits_width
                    do c[i-1] := c[i] od;
                    c[bits_width] := false
               else
                    for i from bits_width by -1 to 2
                    do c[i] := c[i-1] od;
                    c[1] := false
               fi
            od;
            c
       fi;

    op SHR = (bits x, int n) bits: x SHL -n;

>From the above, we see that:

1. The shift count is signed.  It's sign determines the direction of
   shifting, meaning that SHR by a negative count is a left shift, and a
   SHL by a negative count is a right shift.

2. Attempting to shift by more than the width of the bits value, in
   either direction, is a no-op.  No run-time error nor undefined.

3. We don't have signed shifting and its associated problems in Algol
   68, because `bits' values do not have signedness.  The resulting bits
   (conceptually a multiple of booleans) will be interpreted when/if the
   operator ABS is applied to it, resulting in a signed integral value
   which may be negative, but none of that is of relevance in
   unconverted `bits' values.

I am fixing the implementation of these operators in ga68 in order to
follow these semantics, document it in the manual and adding a few
tests.

Salud!


More information about the Algol68 mailing list