Flip bits in two operands and watch AND, OR, XOR, NOT and all three shift operators resolve column by column at 8, 16 or 32-bit width.
Two numbers go in. What happens between them, column by column, is the part textbooks draw badly and a static diagram cannot show at all. Operand A gets a row of clickable cells, operand B gets its own, and the result sits under both. Click any cell and the operand field rewrites itself, every readout recalculates, and the bit-by-bit trace updates to match.
Both fields read three notations independently: plain decimal, 0x hex, and 0b binary. That means 0xBEEF in one field and 13 in the other is a perfectly legal pair. A leading minus works everywhere too. Type -1 at 32-bit width and you get 4294967295 with all thirty-two cells lit, which is the quickest demonstration of two's complement anyone has come up with.
Width is a toggle, not a commitment. Drop 48879 from 32-bit down to 8-bit and the field keeps exactly what you typed while the register wraps to 239, with a line underneath saying so. Keeping the literal and the register visibly separate is the whole point when you are checking whether a value survives a narrowing cast.
The first press of Load Sample Data fills operand A with 0xBEEF and operand B with 13 — one hex literal and one decimal, because the parser takes both and the sample ought to prove it. 0xBEEF is 48879, or 1011 1110 1110 1111 in binary, and it happens to carry 13 set bits of its own. Run all seven operators against that pair at 32-bit width:
A & B = 13, because the low nibble of A is 1111 and 13 is 1101A | B = 48879, unchanged, for the same reason: every bit of B is already set in AA ^ B = 48866 — only bit 1 differs, so only bit 1 flips~A = 4294918416 unsigned, −48880 signed, 0xFFFF4110 in hexA << 13 = 400416768, which is 0x17DDE000A >> 13 and A >>> 13 both = 5That last pair agrees only because A is positive. Click cell 31 in row A to set the sign bit and the two answers separate at once: the arithmetic shift starts copying ones into the vacated high bits while the logical shift keeps feeding zeros. Watching them diverge on the same input is worth more than reading the rule twice.
Open a browser console and evaluate 1 << 32. You get 1, not 0, because JavaScript masks every shift count down to five bits. Evaluate 0xFF00FF00 | 0 and you get −16711936, because the operands were coerced to signed 32-bit first. Those two results are precisely the confusion this page exists to remove, so none of the shifting here goes through << or >>.
Each value is wrapped into the active width, shifted by multiplying or dividing by a power of two, then wrapped again. The boolean operators still run natively, since their bit pattern is correct for any 32-bit input, but each result passes through >>> 0 so the pattern reads back unsigned. The arithmetic right shift builds its sign fill with addition rather than a bitwise OR, which is exact because the shifted value and the fill never occupy the same column.
Operand B doubles as the shift distance, so it can overrun the register without much effort. Press Load Sample twice and B arrives as 0x0F0F0F0F, a distance of 252645135 places.
B % 32; neither answer is honest, so this reports the limit instead.0xFFFFFFFF, not zero. The sign bit has nowhere left to propagate from, so it fills the register.0b1011_0011 and 1'000'000 paste in from Rust or C++ source without hand-editing.The detail most people miss: flipping a cell rewrites the field in whatever notation it already held. Click bit 2 while operand A reads 0xBEEF and the field becomes 0x0000BEEB, zero-padded to the register width, not 48875. Hex stays hex, binary stays binary, and a decimal field stays decimal.
read as hex → 48879 = 0x0000BEEF
read as decimal → 13 = 0x0000000D
Operation
Click any cell in A or B to flip that bit — the operand field rewrites itself in the same notation and every readout follows. Bit 0 is the rightmost column.
Operand A
Operand B
A & B
Result binary
0000 0000 0000 0000 0000 0000 0000 1101Bit-by-bit trace
A result bit is 1 only where both input bits are 1.