Step through set, clear, toggle and test at any bit index, plus popcount, leading and trailing zero counts, lowbit and the power-of-two check.
Setting a bit is one line of code and four things happening at once: a literal 1 sliding left, a mask forming, an OR running, and everything outside the mask surviving untouched. This visualizer pulls those apart into frames you move through with Step Forward and Step Backward, with the mask drawn as its own row underneath the register.
Nine operations are covered. Four rewrite a single bit: set, clear, toggle and test at index n. Five read the register as a whole: population count, leading zeros, trailing zeros, the power-of-two test, and isolating the lowest set bit with x & -x. Every one of them carries its own step trace rather than a shared template, because the interesting part of x & -x has nothing in common with the interesting part of a popcount loop.
Frames are computed ahead of time and indexed into, not replayed. Stepping backward shows you the exact earlier state instead of guessing at an inverse operation, which matters for popcount, where no inverse exists. A scrubber runs the length of the trace, and clicking any line in the transcript jumps straight to it.
On first load the register field holds 0xA5 and the index field holds 3. That is 165, binary 1010 0101, and bit 3 is currently 0, which is deliberate: the default Set Bit operation has something visible to do rather than animating a no-op. Three frames follow.
1 << 3 = 8 = 0x00000008. A single lit cell, everything else dark.x | (1 << 3) = 173 = 0xAD, ringing the one column that moved.Switch to Clear Bit with the same inputs and the trace grows to four frames, because clearing needs the mask inverted first: ~(1 << 3) is 0xFFFFFFF7, all ones except column 3. The result is 165 again, unchanged, and the explanation says so plainly rather than pretending something happened. Toggle twice and you land back where you started, which is the property XOR is actually valued for.
Popcount does not test 32 bits one at a time here. It runs Kernighan's loop, x &= x - 1, which clears the lowest set bit on every pass and therefore iterates once per set bit instead of once per bit of width. For 165 that is 4 passes rather than 32, and each frame shows why: subtracting 1 flips the lowest 1 to 0 and turns on everything below it, so the AND cancels that bit and the borrow together.
The power-of-two check gets three frames for x && !(x & (x - 1)), and the second frame is the one worth pausing on. Lowest-set-bit isolation shows -x as its own row so you can see that x and -x share exactly one lit column. Leading and trailing zero counts walk the register one index per frame and stop at the first 1 they meet.
__builtin_clz(0) and __builtin_ctz(0) are undefined in C and return whatever the hardware felt like. This page reports the full width instead — 32, 16 or 8 depending on the toggle — and says so in the frame.0 & (0 - 1) is 0. The trace walks it: at 32-bit width 0 - 1 wraps to 4294967295, the AND still lands on 0, and the x != 0 guard is what saves the answer.x & -x returns 16, not 1, because the four lowest bits are clear. This is the case people misread the first time they meet a Fenwick tree.Two controls repay finding. The first grid row of any frame stays clickable, so you can flip a bit in the live register mid-trace and watch the whole animation rebuild around it. And whenever an operation writes a result (set, clear or toggle), a button appears offering to push that value back into x, which is how you chain several masks together without retyping anything.
165 = 0x000000A5 · signed 165
operating on bit 3
Bitmask operations — single register
Hardware & CS calculations
Start — the register as it stands
x = 165 = 0x000000A5Bit 3 currently reads 0. Index 0 is the rightmost bit.
Chains operations — the result becomes the register the next one runs against.
Live readouts for x = 165
Popcount
4
__builtin_popcount
CLZ
24
leading zeros
CTZ
0
trailing zeros
MSB index
7
highest set bit
x & -x
1
lowest set bit
Power of 2
no
x && !(x & (x-1))
Register binary
0000 0000 0000 0000 0000 0000 1010 0101Full step transcript — Set Bit
x = 165 = 0x000000A51 << 3 = 8 = 0x00000008x | (1 << 3) = 173 = 0x000000AD