The problem: JavaScript's Number loses precision at 2^53 and your hex conversion is wrong
You need to convert 0xDEADBEEF to binary. You reach for parseInt('DEADBEEF', 16).toString(2) — and JavaScript returns 11011110101011011011111011101111, which is correct. Then you try 0x1FFFFFFFFFFFFF (2^53 - 1) and it still works. Then you try 0x10000000000000000 (2^64) and JavaScript returns 0 because Number can't represent integers above 2^53 — the value silently overflows to a floating-point approximation and the conversion is wrong. The honest move is a converter that uses BigInt as the base unit, parses every input through decimal, and renders to any base — never trusting the floating-point path.
Fastest path
Open the Number Base Converter, type the value, pick the from-base and to-base, read the result.
Input: DEADBEEF (hexadecimal, base 16)
→ Decimal: 3735928559
→ Binary: 1101 1110 1010 1101 1011 1110 1110 1111
→ Octal: 33653337357
→ Base-36: 1ceq4
→ Two's complement (8-bit): overflow
→ Two's complement (32-bit): 11011110101011011011111011101111
→ IEEE 754: 0 | 10011101 | 11011110101011011011111
The tool parsed the hex string through DIGIT_CHARS.indexOf() into a BigInt, then rendered that BigInt in all 12 supported bases simultaneously — binary, octal, decimal, hex, base-32, base-36, ternary, quinary, senary, duodecimal, vigesimal, and base-4. It also computed the two's complement representation at four word sizes (8, 16, 32, 64-bit) and the IEEE 754 single-precision float layout. The rest of this guide is why BigInt is the only honest path, why hex maps 4 bits per digit, why two's complement is asymmetric, and why IEEE 754 has a 127 bias.
The substance: one base unit, one digit alphabet, twelve bases
The BigInt-through-decimal conversion path
The tool never converts directly between two non-decimal bases. Every conversion is two steps: parse the input to a BigInt (parseBaseValue), then render the BigInt to the target base (toBaseString). BigInt is the base unit — the same pattern as the byte converter's "everything goes through bytes."
The parse function iterates each character, looks up its value in DIGIT_CHARS ('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'), and accumulates: result = result * bigBase + BigInt(DIGIT_CHARS.indexOf(ch)). This is positional notation in a loop — each digit multiplies the running total by the radix and adds the digit's value. The render function is the inverse: repeatedly take remaining % bigBase to get the least significant digit, prepend it to the result string, and divide remaining by bigBase. Both functions use BigInt, so they work for numbers of any size — 0xDEADBEEF and 0x10000000000000000 both parse correctly.
JavaScript's Number type is a 64-bit IEEE 754 float — it can represent integers exactly up to 2^53 (9,007,199,254,740,991). Above that, integers lose precision: Number(2^53 + 1) === Number(2^53) is true because the float can't distinguish them. parseInt returns a Number, so parseInt('100000000000000000', 16) silently returns a wrong value. BigInt has no such limit — BigInt('1152921504606846976') is exact. The tool uses BigInt for every conversion, which is why it handles 64-bit hex values, large memory addresses, and cryptographic constants without precision loss.
The digit alphabet and why base-36 is the ceiling
DIGIT_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' is 36 characters — 10 digits plus 26 letters. This is why the tool supports bases 2 through 36 but no higher. Base-36 uses the full alphanumeric set (0-9, A-Z) and is the densest base that can be represented with single-character digits using case-insensitive ASCII. Bases above 36 would need multi-character digits or case sensitivity, both of which create ambiguity.
The tool supports 12 bases across three categories:
| Category | Bases | Use case |
|---|---|---|
| Common | 2, 8, 10, 16 | Binary, octal, decimal, hex — the four bases every programmer uses |
| Programming | 32, 36 | Base-32 for TOTP/2FA codes (RFC 4648), Base-36 for compact URL-safe IDs |
| Mathematical | 3, 4, 5, 6, 12, 20 | Ternary, quinary, senary, duodecimal, vigesimal — historical and theoretical bases |
The mathematical bases are niche but real. Duodecimal (base 12) is advocated by the Dozenal Society because 12 has more divisors than 10 (1, 2, 3, 4, 6, 12 vs 1, 2, 5, 10), making fractions cleaner. Vigesimal (base 20) was used by the Maya. Ternary (base 3) is studied because ternary logic is more efficient than binary in some theoretical models. The tool includes them not because they're practical but because they're the bases people search for when learning number systems.
Why hex is 4 bits per digit and octal is 3
Each hex digit maps to exactly 4 binary bits because 16 = 2^4. 0xF = 1111, 0x0 = 0000. This is why hex is the standard for representing byte values — two hex digits make one byte, and the mapping is unambiguous. The tool's formatGrouped function groups binary digits into 4-bit or 8-bit chunks for readability: 1101111010101101 becomes 1101 1110 1010 1101 (4-bit) or 11011110 10101101 (8-bit).
Each octal digit maps to exactly 3 binary bits because 8 = 2^3. 0o7 = 111, 0o0 = 000. This is why Unix file permissions use octal — chmod 755 is 7 (rwx) 5 (r-x) 5 (r-x), and each octal digit is 3 permission bits. The 3-bit mapping is also why octal doesn't divide evenly into bytes — one byte is 8 bits, which is 2 octal digits plus 2 leftover bits. This awkwardness is why hex replaced octal as the standard byte representation.
Two's complement and the asymmetric range
The tool computes two's complement at four word sizes: 8, 16, 32, and 64-bit. The signed range is asymmetric:
| Word size | Min signed | Max signed | Max unsigned |
|---|---|---|---|
| 8-bit | -128 | 127 | 255 |
| 16-bit | -32,768 | 32,767 | 65,535 |
| 32-bit | -2,147,483,648 | 2,147,483,647 | 4,294,967,295 |
| 64-bit | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 | 18,446,744,073,709,551,615 |
The asymmetry — min is -128 but max is 127 — comes from two's complement encoding. The representation uses the most significant bit as the sign bit, but the negative range includes the value where all bits are 1 (10000000 = -128) while the positive range tops out at 01111111 = 127. There's no +128 in 8-bit signed because that would require a 1 in the sign bit, which is reserved for negatives. The tool flags "overflow" when the input is outside the signed or unsigned range for the selected word size.
The toBinaryString function handles negative numbers by computing maxVal + value — the two's complement encoding. For -1 in 8-bit: 255 + (-1) = 254 = 11111110. For -128: 256 + (-128) = 128 = 10000000. This is the same arithmetic your CPU does; the tool shows you the bits.
IEEE 754 and the 127 bias
The tool renders the IEEE 754 single-precision (32-bit float) layout: 1 sign bit, 8 exponent bits, 23 mantissa bits. The sign bit is 0 for positive, 1 for negative. The exponent is stored with a bias of 127 — the actual exponent is storedExponent - 127. A stored exponent of 128 means an actual exponent of 1; a stored exponent of 127 means an actual exponent of 0. The bias allows the exponent to represent both positive and negative powers without a separate sign bit for the exponent.
The tool uses DataView.setFloat32 to get the raw bytes, then converts each byte to its 8-bit binary string. The output is color-coded: red for the sign bit, blue for the exponent, green for the mantissa. This is the same layout that Float.floatToIntBits in Java and memcpy in C produce — the tool shows you what's actually in memory when you store a float.
The bit-flip visualization and bitwise operations
The tool's Bit Pattern tab renders the value as clickable bit buttons — click any bit to flip it, and the decimal value updates instantly. This is the fastest way to understand bitwise operations: flip the sign bit in an 8-bit value and watch 127 become -1. The word size selector (8, 16, 32, 64) changes the number of bits rendered.
The Bitwise Calculator supports six operations: AND (&), OR (|), XOR (^), NOT (~), left shift (<<), right shift (>>). AND returns 1 only where both bits are 1; OR returns 1 where either bit is 1; XOR returns 1 where the bits differ; NOT flips all bits; left shift multiplies by 2^n; right shift divides by 2^n (with sign extension for signed values). These are the operations that bitmasking, flag systems, and low-level protocol parsing rely on.
Gotchas
- JavaScript's Number loses precision above 2^53.
parseInt('20000000000000000', 16)returns a wrong value becauseNumbercan't represent 2^64. The tool uses BigInt, so it handles 64-bit values correctly. If you're usingparseInt+toStringin your own code, switch to BigInt for values above 2^53. - Two's complement is asymmetric. 8-bit signed ranges from -128 to 127, not -127 to 127. The -128 value has no positive counterpart. The tool shows the exact range for each word size.
- Octal doesn't divide evenly into bytes. One byte is 8 bits = 2 octal digits + 2 leftover bits. This is why hex (2 digits per byte) replaced octal as the standard byte representation.
- IEEE 754 has a 127 bias, not 128. The stored exponent is
actualExponent + 127. A stored exponent of 127 means actual exponent 0 (2^0 = 1). The bias is2^(exponentBits - 1) - 1=2^7 - 1= 127 for single-precision. - Base-36 is case-insensitive.
DIGIT_CHARSuses uppercase A-Z. The tool'sparseBaseValueuppercases the input before parsing, sodeadbeefandDEADBEEFproduce the same value. If you need case-sensitive base-62 (0-9, a-z, A-Z), this tool doesn't support it. - The two's complement overflow flag is per word size.
DEADBEEF(3,735,928,559) fits in 32-bit unsigned but not 32-bit signed (max 2,147,483,647). The tool shows "overflow" for the signed 32-bit interpretation but the correct value for unsigned 32-bit. Check which interpretation your use case needs. - Left shift can overflow silently.
1 << 31in JavaScript (using Number) produces -2147483648 because the sign bit gets set. The tool uses BigInt for shifts, so1n << 63nproduces the correct 64-bit value. Don't rely on JavaScript's<<operator for values above 2^31. - The presets are real values programmers encounter.
0xFF(255),chmod 755(octal),DEADBEEF(hex),0b11111111(max byte),2147483647(max int32). Click any preset to load it and see all 12 base representations. - Text encoding is per-character, not per-string. "Hello" in binary is
01001000 01100101 01101100 01101100 01101111— each character is 8 bits. The tool's text-to-binary encoder usescharCodeAt(0).toString(2).padStart(8, '0')per character. This works for ASCII but not for characters above U+FFFF (emoji, CJK extensions) — those need surrogate pairs and the encoder shows the raw code units, not the code point.
Summary
- Every conversion goes through BigInt as the base unit.
parseBaseValuereads the input into a BigInt usingDIGIT_CHARS.indexOf()per character;toBaseStringrenders the BigInt to any base by repeated% bigBaseand/ bigBase. BigInt prevents the precision loss thatNumbersuffers above 2^53. DIGIT_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'is 36 characters — the digit alphabet for all supported bases. Base-36 is the ceiling because it's the densest case-insensitive single-character base. The tool supports 12 bases across three categories (common, programming, mathematical).- Hex maps 4 bits per digit (16 = 2^4); octal maps 3 (8 = 2^3). This is why hex is the standard for bytes (2 hex digits = 1 byte) and octal is the standard for Unix permissions (3 bits per digit = rwx). The tool groups binary into 4-bit or 8-bit chunks for readability.
- Two's complement is asymmetric. 8-bit signed ranges from -128 to 127 because the sign bit's negative range includes the all-zeros-except-sign value (10000000 = -128) but the positive range tops out at 01111111 = 127. The tool shows signed/unsigned values and overflow flags for 8, 16, 32, and 64-bit word sizes.
- IEEE 754 single-precision is 1 sign + 8 exponent + 23 mantissa with a 127 bias. The stored exponent is
actualExponent + 127. The tool usesDataView.setFloat32to get the raw bytes and color-codes the sign (red), exponent (blue), and mantissa (green) bits. - The bit-flip visualization and bitwise calculator (AND, OR, XOR, NOT, shifts) let you see and manipulate individual bits. Click any bit to flip it; the decimal value updates instantly. This is the fastest way to understand why flipping the sign bit turns 127 into -1.
- Convert at the Number Base Converter; for spreadsheet conversion use CSV to Excel Converter, for JSON tabular conversion use JSON to CSV Converter, and for color format conversion use Color Converter.