RatMinimal web framework

Bit

Bitwise operations live on the bit namespace instead of on infix operators, because every bitwise symbol is already taken in the dialect: & is logical and, | is logical or, << is assignment, >> is a derived field. A namespace sidesteps all of that. Rat ints are 64-bit, so a whole chessboard fits in one int, one bit per square. That is the classic bitboard, and the reason these operations exist.

and / or / xor / not

The combiners

bit.and(a, b), bit.or(a, b), and bit.xor(a, b) combine two integers bit by bit; bit.not(a) flips every bit. Pair them with 0x / 0b literals (Rat reads both) to write masks directly.

<p> [bit.and(0b1100, 0b1010)]
<p> [bit.or(0b1100, 0b1010)]
<p> [bit.xor(0b1100, 0b1010)]
Result

and = 8

or = 14

xor = 6

shl / shr

shr is a LOGICAL shift - no sign smear

bit.shl(x, n) shifts left, bit.shr(x, n) shifts right. shr is a logical (unsigned) shift on purpose: a board with the top bit set is a negative int, and an arithmetic shift would drag 1s down across the high bits and corrupt it. A shift past the 64-bit width yields 0.

<p> [bit.shl(1, 4)]
<p> [bit.shr(256, 4)]
Result

1 << 4 = 16

256 >> 4 = 16

count / lsb / msb

Population count and set-bit indices

bit.count(x) is the population count (how many bits are set). bit.lsb(x) and bit.msb(x) return the index of the lowest and highest set bit (0 = least significant), or -1 when no bits are set. lsb is the bitboard iteration primitive: read the lowest set square, clear it, repeat.

<p> [bit.count(255)]
<p> [bit.lsb(40)]
<p> [bit.msb(40)]
Result

count(255) = 8

lsb(40) = 3

msb(40) = 5

A bitboard

One int, 64 squares

Treat an int as a board: bit s is square s. Set a square by OR-ing in a shifted 1; test one by shifting it down and masking. Because shr is logical, the top-left square (bit 63) reads back cleanly even though it makes the int negative.

> set_sq[bb, s] >> bit.or(bb, bit.shl(1, s))
> has_sq[bb, s] >> bit.and(bit.shr(bb, s), 1) == 1

> page
board: set_sq(set_sq(0, 0), 63)

<p> a1 set: [has_sq(board, 0)]
<p> h8 set: [has_sq(board, 63)]
<p> squares occupied: [bit.count(board)]

See also Math · Conversion · JSON