Number Base Converter

Bidirectional conversion between Binary (Base 2), Octal (Base 8), Decimal (Base 10), Hexadecimal (Base 16), and arbitrary radixes (Base 2–36) with signed two's complement and word-length modeling.

Mode & Width
Presets:
Decimal (Base 10)Standard
Digits: 0–93 chars
Hexadecimal (Base 16)0x
Symbols: 0–9, A–F1 bytes
Binary (Base 2)0b
Symbols: 0, 18 bits
Octal (Base 8)0o
Digits: 0–73 digits
Custom Base
Radix:
Alphabet: 0–9, a–z (2–36)2 symbols

Converter Configuration Guide

Radix SelectionDirect entry across Binary, Octal, Decimal, Hexadecimal, or configure any custom radix between Base 2 and Base 36.
Word-Length RegisterConstrain calculations to physical architecture sizes (8-bit Byte, 16-bit Short, 32-bit Int, 64-bit Long) or unconstrained BigInt.
Signed Two's ComplementToggle signed mode to represent negative values using standard CPU arithmetic inversion and modular wrap-around.
Syntax FormattingDisplay programming prefixes (0b, 0o, 0x), nibble/byte grouping spaces, or uppercase hex characters.

Radix Cheat Sheet & Bit-Chunking Mental Math

In software development, converting between Binary, Octal, Decimal, and Hexadecimal rarely requires arithmetic division. Because 8 (2³) and 16 (2⁴) are exact powers of 2, bits map directly to single digits:

Decimal4-Bit Binary (Nibble)Hexadecimal3-Bit BinaryOctal
0000000000
1000110011
2001020102
3001130113
4010041004
5010151015
6011061106
7011171117
810008——
910019——
101010A——
111011B——
121100C——
131101D——
141110E——
151111F——
Binary ↔ Hex 4-Bit Chunking

Group bits into 4-element nibbles from right to left. Each 4-bit chunk translates directly into one hex character:

Binary:  1101 0110
Nibbles: 1101 (D)  0110 (6)
Hex:     0xD6 (= 214 unsigned or -42 signed)
Direct Hex ↔ Octal Bridge

Convert without base 10 arithmetic by expanding hex to binary and regrouping into 3-bit slices:

Hex:     0x5B
Expand:  0101 1011 (8 bits)
Regroup: 001 011 011
Octal:   0o133 (1×64 + 3×8 + 3 = 91)

Two's Complement Debugging: The High-Nibble Sign Rule

CPUs do not store a separate minus sign (-). Negative numbers are encoded using Two's Complement, where the most significant bit (MSB) has negative weight. This allows arithmetic addition circuits to handle subtraction directly: A - B = A + (~B + 1).

The High-Nibble Rule (Instant Sign Check)

In any fixed-width hex dump, look at the very first hexadecimal digit:

  • 8, 9, A, B, C, D, E, F: Top bit is 1 → Negative in signed mode.
  • 0, 1, 2, 3, 4, 5, 6, 7: Top bit is 0 → Positive or Zero.
0xFF = -1 (8-bit)  |  0x7F = +127 (8-bit)
Sign Extension in Type Casting

When widening a signed integer (e.g. int8_t → int32_t), the CPU copies the MSB into all newly added upper bits to preserve the negative value:

8-bit:   0xD6 (-42)
16-bit: 0xFFD6 (-42, upper byte sign-extended)
32-bit: 0xFFFF FFD6 (-42, upper 3 bytes sign-extended)
Decimal Value8-Bit Binary8-Bit Hex16-Bit Hex32-Bit HexHardware Interpretation
+127 (Max Int8)0111 11110x7F0x007F0x0000 007FHighest positive 8-bit signed value
+10000 00010x010x00010x0000 0001Unit increment
00000 00000x000x00000x0000 0000Single unambiguous zero
-11111 11110xFF0xFFFF0xFFFF FFFFAll bits active (all 1s)
-421101 01100xD60xFFD60xFFFF FFD6Bitwise inversion + 1 (~42 + 1)
-128 (Min Int8)1000 00000x800xFF800xFFFF FF80Lowest negative 8-bit boundary

Word-Length Register Boundaries & Overflow Wrap-Around

In physical hardware, registers operate on fixed bit widths. When an operation exceeds register limits, high bits are truncated modulo 2ᵟ, wrapping values around. Use the table below to verify data type bounds:

Register WidthUnsigned Range [0, 2ᴺ - 1]Signed Range [-2ᴺ⁻¹, 2ᴺ⁻¹ - 1]Max Hex ValueLanguage Types (Rust / C / Go)
8-bit (Byte)0 to 255-128 to +1270xFFu8 / i8, uint8_t / int8_t, byte
16-bit (Word)0 to 65,535-32,768 to +32,7670xFFFFu16 / i16, uint16_t / int16_t
32-bit (DWord)0 to 4,294,967,295-2,147,483,648 to +2,147,483,6470xFFFF FFFFu32 / i32, uint32_t / int32_t
64-bit (QWord)0 to 18,446,744,073,709,551,615-9,223,372,036,854,775,808 to +9,223,372,036,854,775,8070xFFFF FFFF FFFF FFFFu64 / i64, uint64_t / int64_t
Auto (BigInt)0 to ∞ (Memory bound)-∞ to +∞ (Memory bound)DynamicBigInt (JS), int (Python 3), big.Int (Go)
Integer Overflow in Practice

When adding 1 to a signed 32-bit maximum (0x7FFF FFFF / +2,147,483,647), the binary value increments to 0x8000 0000. Because the MSB becomes 1, the value wraps around to the lowest negative boundary: -2,147,483,648. Selecting fixed bit widths in our tool models this exact register truncation.

Base 36 in Real-World Systems: URL Slugs and Database ID Compression

While binary and hex dominate low-level memory inspection, higher radices solve data storage and transmission constraints:

Base 36 (Alphanumeric 0–9, A–Z)

Case-insensitive representation using all 10 digits and 26 English letters. Because it never produces percent-encoding artifacts (%2B, %2F), it is the standard for compressing auto-incrementing integer IDs into clean URL slugs (e.g. Reddit comment keys, shortened link tokens).

342,551,797 → 5NY2NP (6 chars)
Base 32 (RFC 4648)

Uses 32 characters (A–Z, 2–7), omitting visually ambiguous characters (0/O, 1/I/L, 8/B). Engineered specifically for human manual entry, such as Google Authenticator 2FA secret setup keys and Tor .onion addresses.

JBSWY3DPEHPK3PXP (TOTP Seed)
Base 64 (Byte Stream Transport)

Unlike Base 36 which represents a single numeric integer, Base 64 is a byte-serialization scheme. It packs 6 bits per character to safely transmit arbitrary binary images, tokens, and cryptographic keys over 7-bit ASCII protocols (HTTP headers, JSON, MIME email).

data:image/png;base64,iVBORw...

Programming Language Numeric Literals & Bitmasking Reference

Compilers interpret raw numbers as base 10 by default. Use standardized prefixes to declare non-decimal literal constants:

LanguageBinary PrefixOctal PrefixHex PrefixDigit Separators
JavaScript / TypeScript0b / 0B0o / 0O0x / 0XUnderscore: 0xFF_FF
Python 30b / 0B0o / 0O0x / 0XUnderscore: 0b1111_0000
Rust0b0o0xUnderscore: 0xDEAD_BEEF
Go (Golang)0b / 0B0o / 0O0x / 0XUnderscore: 0_644
C / C++0b / 0B (C++14 / C23)0 (legacy) / 0o (C23)0x / 0XSingle quote (C++): 0xFF'FF
Common Bitmask Idioms in Production
Set Bit nflags |= (1 << n)
Clear Bit nflags &= ~(1 << n)
Toggle Bit nflags ^= (1 << n)
Test Bit n(flags & (1 << n)) != 0

Production Code Snippets Across Languages

Practical methods to parse and format integers across radices (2 to 36) in production backends:

TypeScript & JavaScript (BigInt & Radix 2–36)
// BigInt converts losslessly to any radix string from 2 to 36
const val = 3735928559n;
const hex = val.toString(16); // "deadbeef"
const b36 = val.toString(36); // "1ps9wxb"

// Parse strings back to integer
const parsedHex = BigInt('0x' + hex); // 3735928559n

// Simulate 8-bit Two's Complement signed wrap-around
const signed8 = BigInt.asIntN(8, -42n);   // -42n
const unsigned8 = BigInt.asUintN(8, -42n); // 214n (0xD6)
Python 3 (Built-in Radix Functions)
# Format integer to binary, octal, hex
num = 3735928559
bin_str = bin(num)  # '0b11011110101011011011111011101111'
hex_str = hex(num)  # '0xdeadbeef'

# Parse strings of any radix from 2 to 36
val_from_hex = int("DEADBEEF", 16)  # 3735928559
val_from_b36 = int("1ps9wxb", 36)   # 3735928559
Go (strconv Package)
package main

import (
    "fmt"
    "strconv"
)

func main() {
    val := int64(3735928559)

    // FormatInt supports any base from 2 to 36
    hexStr := strconv.FormatInt(val, 16) // "deadbeef"
    b36Str := strconv.FormatInt(val, 36) // "1ps9wxb"

    // Parse with explicit base
    parsed, _ := strconv.ParseInt(hexStr, 16, 64)
    fmt.Println(parsed) // 3735928559
}
Rust (std::fmt & from_str_radix)
fn main() {
    let val: u32 = 0xDEAD_BEEF;

    // Format strings
    let bin_str = format!("{:b}", val);
    let hex_str = format!("{:X}", val); // "DEADBEEF"

    // Parse from radix (2 to 36)
    let parsed = u32::from_str_radix("DEADBEEF", 16).expect("valid hex");
    assert_eq!(val, parsed);
}

Frequently Asked Questions

Why does my hex output show 0xFF or 0xFFFFFFFF instead of a negative sign for -1?

Computer memory and processor registers do not store independent "-" glyphs. Negative numbers are stored in Two's Complement notation. In Two's Complement, -1 is represented by setting every bit in the word to 1 (all bits active). In an 8-bit register, all 1s equals binary 1111 1111, which displays as hexadecimal 0xFF. In a 32-bit register, 32 consecutive 1s equals 0xFFFF FFFF. When you toggle the "Signed" option in this converter, it interprets the most significant bit (MSB) as negative weight, correctly resolving 0xFF to -1 in 8-bit mode.

How can developers instantly tell if a hexadecimal number represents a negative value?

Inspect the leading (most significant) hexadecimal digit. Because each hex character represents 4 binary bits (8, 4, 2, 1), any hex character from 8 through F has its highest bit set to 1 (8 = 1000₂, 9 = 1001₂, A = 1010₂, ..., F = 1111₂). In signed two's complement registers, a leading MSB of 1 signifies a negative value. If the leading digit is 0 through 7 (where the MSB is 0), the number is positive or zero.

What is the practical difference between arithmetic shift (>>) and logical shift (>>>)?

In binary bitwise manipulation, an arithmetic right shift (>>) preserves the sign bit: if the number is negative (MSB is 1), it fills newly vacated bit positions on the left with 1s (sign extension). A logical right shift (>>>) ignores signedness and unconditionally shifts in 0s from the left, transforming negative numbers into large positive unsigned integers. For example, in 32-bit: (-42 >> 1) remains -21, whereas (-42 >>> 1) yields 2,147,483,627.

Why does native JavaScript lose precision for integers above 53 bits without BigInt?

Standard JavaScript Number primitives follow IEEE-754 double-precision floating-point format, allocating 53 bits to the significand (mantissa), 11 bits to the exponent, and 1 sign bit. Integers greater than Number.MAX_SAFE_INTEGER (9,007,199,254,740,991, or 2⁵³ - 1) cannot be uniquely represented and suffer rounding collapse. BigInt bypasses the floating-point unit by storing arbitrary-precision integers as dynamically allocated arrays of 64-bit machine limbs, ensuring lossless conversion across 64-bit, 128-bit, and 256-bit keys.

Why do UNIX file permissions (chmod 755) map cleanly to octal numbers?

UNIX file security divides access permissions into three discrete bit flags—Read (4, 2²), Write (2, 2¹), and Execute (1, 2⁰)—across three target entities: User (Owner), Group, and Other. Because 2³ = 8, each 3-bit permission cluster exactly matches a single octal digit from 0 (---) to 7 (rwx). A mode string like rwxr-xr-x breaks down into [111] (7), [101] (5), and [101] (5), eliminating bit-shifting conversions.

How does sign extension work when casting an 8-bit integer into a 32-bit register?

When an 8-bit signed integer is widened to 32 bits, the hardware must preserve its negative mathematical value. If the 8-bit value is -42 (binary 1101 0110, hex 0xD6), zero-extending it would produce 0x0000 00D6 (+214). Sign extension copies the 8th bit (1) across all upper 24 bits, producing 0xFFFF FFD6 (binary 1111...1101 0110), which correctly evaluates to -42 in 32-bit two's complement.

Why is Base 36 preferred over Base 64 for database sequential IDs and URL slugs?

Base 36 uses digits 0–9 and Latin letters A–Z (36 characters) and is completely case-insensitive. This prevents human transcription confusion and guarantees that URLs remain clean and readable without percent-encoding (%2B, %2F). While Base 64 is more compact, its case-sensitivity (distinguishing "a" from "A") and inclusion of symbols (+, /, =) can cause routing collisions on case-insensitive filesystems or require URL-safe variants (RFC 4648 Base64URL).

How do bitmasking operations use hexadecimal constants like 0x0F and 0xFF?

Because one hexadecimal digit represents exactly 4 binary bits (one nibble) and two hex digits represent an 8-bit byte, hexadecimal provides a visual template for bitmasks. The constant 0x0F (binary 0000 1111) masks out the upper 4 bits and extracts the lower nibble. The constant 0xFF (binary 1111 1111) extracts individual bytes from 32-bit words, such as extracting RGB color channels: (color >> 16) & 0xFF extracts the Red byte.