Bitwise operations

constant MAXINT = uint.Range.max;
constant BITS = MAXINT.base(2).chars;

# define rotate ops for the fun of it
multi sub infix:<⥁>(Int:D \a, Int:D \b) { :2[(a +& MAXINT).polymod(2 xx BITS-1).list.rotate(b).reverse] }
multi sub infix:<⥀>(Int:D \a, Int:D \b) { :2[(a +& MAXINT).polymod(2 xx BITS-1).reverse.list.rotate(b)] }

sub int-bits (Int $a, Int $b) {
    say '';
    say_bit "$a", $a;
    say '';
    say_bit "2's complement $a", +^$a;
    say_bit "$a and $b", $a +& $b;
    say_bit "$a or $b",  $a +| $b;
    say_bit "$a xor $b", $a +^ $b;
    say_bit "$a unsigned shift right $b", ($a +& MAXINT) +> $b;
    say_bit "$a signed shift right $b", $a +> $b;
    say_bit "$a rotate right $b", $a ⥁ $b;
    say_bit "$a shift left $b", $a +< $b;
    say_bit "$a rotate left $b", $a ⥀ $b;
}

int-bits(7,2);
int-bits(-65432,31);

sub say_bit ($message, $value) {
    printf("%30s: %{'0' ~ BITS}b\n", $message, $value +& MAXINT);
}

Output:

                             7: 0000000000000000000000000000000000000000000000000000000000000111

              2's complement 7: 1111111111111111111111111111111111111111111111111111111111111000
                       7 and 2: 0000000000000000000000000000000000000000000000000000000000000010
                        7 or 2: 0000000000000000000000000000000000000000000000000000000000000111
                       7 xor 2: 0000000000000000000000000000000000000000000000000000000000000101
      7 unsigned shift right 2: 0000000000000000000000000000000000000000000000000000000000000001
        7 signed shift right 2: 0000000000000000000000000000000000000000000000000000000000000001
              7 rotate right 2: 1100000000000000000000000000000000000000000000000000000000000001
                7 shift left 2: 0000000000000000000000000000000000000000000000000000000000011100
               7 rotate left 2: 0000000000000000000000000000000000000000000000000000000000011100

                        -65432: 1111111111111111111111111111111111111111111111110000000001101000

         2's complement -65432: 0000000000000000000000000000000000000000000000001111111110010111
                 -65432 and 31: 0000000000000000000000000000000000000000000000000000000000001000
                  -65432 or 31: 1111111111111111111111111111111111111111111111110000000001111111
                 -65432 xor 31: 1111111111111111111111111111111111111111111111110000000001110111
-65432 unsigned shift right 31: 0000000000000000000000000000000111111111111111111111111111111111
  -65432 signed shift right 31: 1111111111111111111111111111111111111111111111111111111111111111
        -65432 rotate right 31: 1111111111111110000000001101000111111111111111111111111111111111
          -65432 shift left 31: 1111111111111111100000000011010000000000000000000000000000000000
         -65432 rotate left 31: 1111111111111111100000000011010001111111111111111111111111111111

Last updated