librarylibs/Bits/src/Bits.xtl
Bits: bits -- binary digits and back, popcount, and, or, xor on whole numbers, shifts, single bits, Gray codes. Import it with an alias of your choice: "b:" u_se< "Bits". Put libs/Bits/src on XETAL_PATH ("just path"); the reference is libs/Bits/docs. Names with l: are exported; those under h: are private to this file.
Numbers are whole and at least 0 (up to 2^62); bit 0 is the lowest. The logic works on every item at once: the numbers are taken apart into bits with e_ncode, combined with the built-in &, | and !=, and put back together with d_ecode. On vectors of bits those built-ins are the logic already.
Columns and value
ʰc̲ols : Int -> Int
The w bits of each number, one column per number.
ʰc̲ols ← { x → '∨ r̲/ r̲avel x < 0 ? @ p̲anic< "Bits works on whole numbers 0 or more, not {x}" (w r̲eshape 2) e̲ncode x }
ˡb̲its : Int -> Int -> Int
n b_its x: the low n bits of each number, most significant first: a vector for one number, a row per number for several.
ˡb̲its ← { n x → '∨ r̲/ r̲avel x < 0 ? @ p̲anic< "Bits works on whole numbers 0 or more, not {x}" o̲\ (n r̲eshape 2) e̲ncode x }
ˡv̲alue : Num a => a -> a
v_alue bits: the number each row of bits (or the vector) stands for.
ˡv̲alue ← { bits → 2 d̲ecode o̲\ bits }
Bit by bit
ˡp̲opcount : Int -> Int
p_opcount x: how many 1 bits each number has.
ˡp̲opcount ← { x → '+ r̲/ ʰc̲ols x }
ˡa̲nd : Int -> Int -> Int
a a_nd b, a o_r b, a x_or b: bit by bit, item by item (a single number on either side goes with every item of the other: a + 0 * b has the shape of both). On 0/1 digits: and is the smaller, or the larger, xor the distance; Int arithmetic keeps the result an Int (a comparison such as & would leave its numeric type to the caller: ask X17).
ˡa̲nd ← { a b → 2 d̲ecode (ʰc̲ols a + 0 × b) m̲in ʰc̲ols b + 0 × a }
Shifts and masks
ˡs̲hl : Num a => a -> a -> a
n s_hl x, n s_hr x: each number shifted n bits left (times 2^n) or right (halved n times, dropping the bits shifted out).
ˡs̲hl ← { n x → x × 2 ^ n }
ˡb̲it? : Truthy a => Int -> Int -> a
i b_it? x: whether bit i of each number is 1.
ˡb̲it? ← { i x → 1 = (x d̲iv 2 ^ i) m̲od 2 }