ilusm.dev

bit

Bitwise operations and bit manipulation - AND, OR, XOR, NOT, shifts, rotations, individual bit access, masks, popcount, first/last set bit, byte conversion, flags, and power-of-2 helpers.

Load with: use bit

What this module does

bit provides a complete set of bit manipulation tools as named functions. The language already has band, bor, bxor, ~, <<, and >> built in - bit wraps those into named functions and adds higher-level utilities: test/set/clear/toggle individual bits, build masks from a list of positions, count set bits (popcount), find the first and last set bits, convert integers to byte lists and back, extract and insert bit fields, check/add/remove flag values, rotate, XOR-swap, and power-of-2 tests and rounding.

All operations work on signed ilusm integers. The unsigned right-shift bitur treats the value as unsigned by adding 4294967296 if negative before shifting. All functions are also accessible via the bit object.

Quick example

use bit

# Basic ops
prn(bitan(0b1010, 0b1100))  # 8  (0b1000)
prn(bitor(0b1010, 0b0101))  # 15 (0b1111)
prn(bitxo(0b1010, 0b1100))  # 6  (0b0110)

# Test and set individual bits
v = 0
v = bitse(v, 3)   # set bit 3
prn(bitst(v, 3))  # tru
v = bitcl(v, 3)   # clear bit 3
prn(bitst(v, 3))  # fls

# Popcount and power-of-2
prn(bitct(0b10110110))  # 5
prn(bitp2(64))           # tru
prn(btnp2(100))          # 128

Functions

Basic bitwise operations

bitan(a, b) / bit.and(a, b)

Bitwise AND of a and b.

bitor(a, b) / bit.or(a, b)

Bitwise OR.

bitxo(a, b) / bit.xor(a, b)

Bitwise XOR.

bitnt(a) / bit.not(a)

Bitwise NOT (one's complement).

bitls(a, n) / bit.shl(a, n)

Left shift a by n bits.

bitrs(a, n) / bit.shr(a, n)

Arithmetic right shift a by n bits (sign-extending).

bitur(a, n) / bit.ushr(a, n)

Unsigned (logical) right shift. Converts negative values to unsigned by adding 4294967296 before shifting.

Individual bit access

bitst(v, p) / bit.test(v, p)

Returns tru if bit at position p is set, fls otherwise.

bitse(v, p) / bit.set(v, p)

Sets bit at position p. Returns the new value.

bitcl(v, p) / bit.clear(v, p)

Clears (zeroes) bit at position p. Returns the new value.

bitto(v, p) / bit.toggle(v, p)

Flips bit at position p. Returns the new value.

Masks and counting

bitmk(ps) / bit.mask(ps)

Builds a bitmask with bits set at all positions listed in ps. E.g. bitmk([0, 2, 4])0b10101.

bitct(v) / bit.popcount(v)

Counts the number of set bits (population count). Shifts right one bit at a time, counting 1s.

bitff(v) / bit.ffs(v)

Find first set bit - returns the position (0-indexed) of the lowest set bit. Returns -1 if v is 0.

bitfl(v) / bit.fls(v)

Find last set bit - returns the position of the highest set bit. Returns -1 if v is 0.

Byte conversion

bitby(n) / bit.to_bytes(n)

Converts integer n to a little-endian byte list. Extracts bytes by masking the low 8 bits and shifting right by 8 each time. Returns [0] for 0.

bitfr(bs) / bit.from_bytes(bs)

Reconstructs an integer from a little-endian byte list.

btbbe(n) / bit.to_bytes_be(n)

Converts integer n to a big-endian byte list. Prepends each byte.

btfrb(bs) / bit.from_bytes_be(bs)

Reconstructs an integer from a big-endian byte list.

Bit fields

bitgt(v, s, e) / bit.get_field(v, s, e)

Extracts the bit field from bit position s (inclusive) to e (exclusive). Returns the value of those bits, shifted down to start at bit 0.

btstf(v, s, e, n) / bit.set_field(v, s, e, n)

Sets the bit field from position s to e in v to the value n. Masks n to fit the field width. Returns the updated integer.

Flags

bitck(v, fl) / bit.check(v, fl)

Returns tru if all bits in the flag mask fl are set in v. (v AND fl) == fl.

bitad(v, fl) / bit.add(v, fl)

Sets all bits in flag mask fl in v. Returns the new value.

bitrm(v, fl) / bit.remove(v, fl)

Clears all bits in flag mask fl from v. Returns the new value.

Rotation

bitrl(v, n) / bit.rotl(v, n)

Rotates v left by n bits (32-bit rotation). n is normalised to 0–31.

bitrr(v, n) / bit.rotr(v, n)

Rotates v right by n bits (32-bit rotation).

Swap and power-of-2

bitwp(a, b) / bit.swap(a, b)

XOR-swaps two values without a temporary variable. Returns {a, b} with values exchanged.

bitp2(n) / bit.is_pow2(n)

Returns tru if n is a power of 2. Uses the classic n != 0 AND (n AND n-1) == 0 test.

btnp2(n) / bit.next_pow2(n)

Returns the smallest power of 2 greater than or equal to n. Uses bitwise OR with shifted copies to fill in all lower bits, then adds 1.

btlp2(n) / bit.prev_pow2(n)

Returns the largest power of 2 less than or equal to n. Same fill technique, then shifts the result right by 1.

Notes

  • All functions operate on ilusm integers. Negative values behave as signed integers in most operations except bitur (unsigned right shift) which explicitly converts to unsigned.
  • Rotation functions normalise n to 0–31 using n % 32.
  • All functions are available both as top-level names (bitan, bitor, etc.) and as the bit object (bit.and, bit.or, etc.).
  • No dependencies - pure ilusm using only the language's built-in bitwise operators.