- What does each operation do?
- AND (&): a bit is 1 only if both inputs have 1. Used for masking. OR (|): a bit is 1 if either input has 1. Used to set bits. XOR (^): a bit is 1 if the inputs differ. Used to toggle bits and in checksums. NOT (~): flip every bit; for signed integers, ~x = -x - 1. Left shift (<<): slide bits left, fill with zeros — each shift multiplies by 2. Right shift (>>): slide right, fill the left with the sign bit — each shift divides by 2 (rounding toward minus infinity). Unsigned right shift (>>>): treat the value as unsigned 32-bit, slide right, fill the left with zeros.
- Why does AND act like a mask?
- AND with a value that has 1s only in the positions you want to keep zeros out the rest. To extract the low byte of a 32-bit value, AND it with 0xff (which is binary 0000...0000_11111111). Bits where the mask is 1 pass through unchanged; bits where the mask is 0 are forced to 0. This is how you isolate a single byte, check whether a flag bit is set, or strip the sign bit.
- Why does NOT of a positive number turn negative?
- Because integers in most languages are stored in two's-complement form. The high bit signals the sign. When you flip every bit of 5 (which has its high bit 0), the result has its high bit 1, which is interpreted as a negative value. In two's complement, ~x = -x - 1 exactly. So ~5 = -6, ~0 = -1, ~(-1) = 0. There's nothing wrong — it's just how signed integers are encoded.
- What's the difference between >> and >>> ?
- >> is arithmetic right shift: it slides bits right and fills the left side with copies of the sign bit. -1 >> 1 stays -1 (all-ones, all-ones). >>> is unsigned (logical) right shift: it fills the left with zeros instead of the sign bit. -1 >>> 1 becomes 2147483647 (the largest positive 32-bit value). >>> only makes sense on the low 32 bits, so this calculator caps the shift amount at 31 for >>>.
- Why BigInt instead of plain JavaScript numbers?
- JavaScript's regular bitwise operators on numbers silently truncate to signed 32-bit. So 1 << 40 in plain JS is 256 (because 40 modulo 32 is 8), not 1099511627776 as it should be. BigInt has no such cap — shifts and bitwise ops work on arbitrary-precision integers. This matters for cryptography, color packing, address math, and anything else where 32 bits isn't enough. The 32-bit grid still shows the low 32 bits, but the numeric outputs are the full BigInt result.
- How do I read the 32-bit grid?
- The grid has 32 cells from left (bit 31, the high bit / sign bit) to right (bit 0, the low bit). Green cells are 1, neutral cells are 0. To check whether bit N is set, count from the right starting at 0. The position labels under the grid (31-24, 23-16, 15-8, 7-0) mark the byte boundaries — useful when you're working with packed structures, color channels, or status flags.
- Can I enter negative numbers?
- Yes. Type a leading minus before any base: '-5', '-0xff', '-0b1010'. Negatives are represented in two's-complement when shown in the 32-bit grid, so -1 fills the grid with all 1s, -2 fills it with 1s except the lowest bit, and so on. The hex/binary/octal numeric outputs use a signed representation with a leading minus — '-0xff' rather than the two's-complement bit pattern — which is the convention BigInt.toString() uses.
- What's a real-world use for XOR?
- XOR has three classic uses. (1) Toggling bits — XOR with a mask flips exactly the bits the mask sets to 1. (2) Cheap checksums — XOR all bytes of a message together; the receiver does the same and compares. RAID parity uses this. (3) One-time-pad-style encryption — XOR a plaintext with a key, XOR the ciphertext with the same key to recover. XOR is also self-inverse: x ^ y ^ y = x, which is why it's useful for swapping variables without a temporary in low-level code.