DEV Community

Anup Karanjkar
Anup Karanjkar

Posted on • Originally published at wowhow.cloud

Binary, Hex & Octal — Number Systems Every Developer Must Know

Every time you type chmod 755, set a color to #FF5733, or write permissions & 0x0F in a production codebase, you are doing number system arithmetic. Binary, hexadecimal, and octal are not abstract CS theory you clear from memory after your first algorithms exam. They are the language your operating system, CPU, and network stack speak natively — and fluency pays dividends in code quality, debugging speed, and interview performance.

This guide covers all four number bases you need as a developer — binary, octal, decimal, and hexadecimal — plus two's complement for negative numbers, bitwise operations with practical examples, and a set of performance tricks your CPU rewards with faster execution. Practice every example at the free binary converter tool on WOWHOW — no signup, instant conversion between all bases.

Why Number Systems Matter Beyond CS Class

The Stack Overflow Developer Survey has consistently found that bit manipulation and number base fluency are among the top skills separating senior from mid-level developers, particularly in systems programming, embedded development, and security engineering. But the truth is these skills appear in ordinary web and application development far more than most developers realize.

Memory addresses in debuggers display as hex. Network subnets are defined by binary masks. File permissions use octal. Color values in CSS, image processing, and graphics APIs are hex. Feature flags, access control bitfields, and configuration masks are binary operations in disguise. When a production bug stems from a permissions issue or a bitwise operator applied incorrectly, understanding the underlying number system is the fastest path to the root cause.

The four bases you need are:

  • Binary (base 2) — the native language of hardware

  • Octal (base 8) — Unix file permissions

  • Decimal (base 10) — human-readable arithmetic

  • Hexadecimal (base 16) — compact binary representation for memory, colors, encodings

Binary: What Your CPU Actually Sees

Every value a computer stores — numbers, text, images, code — is ultimately a sequence of bits, where each bit is either 0 or 1. Binary (base 2) uses powers of 2 as place values. The rightmost bit is the ones place (2⁰ = 1), the next is the twos place (2¹ = 2), then fours (2²), eights (2³), and so on.

The 8-bit binary number 10110101 converts to decimal like this:

1×128 + 0×64 + 1×32 + 1×16 + 0×8 + 1×4 + 0×2 + 1×1
= 128 + 32 + 16 + 4 + 1
= 181
Enter fullscreen mode Exit fullscreen mode

Eight bits make one byte, which can represent 256 distinct values (0–255). This is why RGB color channels go from 0 to 255 — each is one byte. A 32-bit integer has four bytes and can represent about 4.3 billion values unsigned. Modern systems work in 64-bit words, giving a range of over 18 quintillion values.

When you declare an int in C or a number in JavaScript (which uses IEEE 754 double-precision floating point), you are working with a fixed-width binary representation under the hood. Understanding this explains why Number.MAX_SAFE_INTEGER in JavaScript is 9,007,199,254,740,991 — it is 2⁵³ − 1, the largest integer a 64-bit float can represent without losing precision.

Converting Decimal to Binary

Divide repeatedly by 2, record the remainders from bottom to top:

181 ÷ 2 = 90 remainder 1  ← least significant bit
 90 ÷ 2 = 45 remainder 0
 45 ÷ 2 = 22 remainder 1
 22 ÷ 2 = 11 remainder 0
 11 ÷ 2 =  5 remainder 1
  5 ÷ 2 =  2 remainder 1
  2 ÷ 2 =  1 remainder 0
  1 ÷ 2 =  0 remainder 1  ← most significant bit

Result (bottom to top): 10110101
Enter fullscreen mode Exit fullscreen mode

Verify immediately at the binary converter — paste any decimal number and confirm the binary output matches your hand calculation. This is how you build number system intuition fast.

Hexadecimal: Binary for Humans

Binary strings get long and unreadable fast. A 32-bit IPv4 address in binary is 32 characters. A 64-bit memory address is 64 characters. Hexadecimal compresses this by grouping every 4 bits into a single hex digit — because 2⁴ = 16, the base of hexadecimal.

Hex uses digits 0–9 and letters A–F, where A = 10, B = 11, C = 12, D = 13, E = 14, F = 15. One hex digit represents exactly 4 bits. Two hex digits represent one byte (0–255). This is why byte values appear everywhere as two-digit hex pairs.

Converting binary to hex is mechanical — split into groups of 4 bits and convert each group:

Binary:  1011  0101
         ↓       ↓
Hex:      B      5
Result: 0xB5 = 181 decimal
Enter fullscreen mode Exit fullscreen mode

The 0x prefix signals hexadecimal in most programming languages. You will see it in memory addresses (0x7FFE4A2B), CSS colors (#FF5733 — same format without the prefix), and byte-level data manipulation.

Hex in Real Code

CSS colors are three hex pairs: red, green, blue, each 0–255 as two hex digits.

/* CSS color: #FF5733 */
Red:   0xFF = 255
Green: 0x57 = 87
Blue:  0x33 = 51

/* Or use rgb() for the same values */
color: rgb(255, 87, 51);
Enter fullscreen mode Exit fullscreen mode

Memory addresses in a debugger or crash dump look like 0x00007FFE4A2B3C10 — a 64-bit address in 16 hex digits. When you are reading a stack trace or a memory dump during debugging, hex is the native representation. Developers who cannot convert hex to decimal mentally take significantly longer to interpret debugger output.

Hash values from cryptographic functions like SHA-256 are displayed as hex strings — 64 hex characters representing 256 bits. The hash generator tool on WOWHOW lets you generate and inspect these values directly.

Octal: The File Permissions System

Octal (base 8) uses digits 0–7 and groups 3 bits per digit. Its primary practical application for developers is Unix/Linux file permissions — a system that has been standard since the 1970s and is still how every Linux server, macOS machine, and container runtime manages file access.

The chmod command takes an octal number representing three permission triplets:

chmod 755 myfile

7 = 111 in binary = read (4) + write (2) + execute (1) = owner has all permissions
5 = 101 in binary = read (4) + execute (1) = group can read and execute
5 = 101 in binary = read (4) + execute (1) = others can read and execute
Enter fullscreen mode Exit fullscreen mode

Breaking down the octal number 755: each digit maps to one of the three permission groups (owner, group, others). Each digit is 3 bits. Bit 2 is read (r), bit 1 is write (w), bit 0 is execute (x). Adding up the set bits gives the octal value.

Common chmod values:
755 → rwxr-xr-x  (executable scripts, directories)
644 → rw-r--r--  (regular files, configs)
600 → rw-------  (private keys, secrets)
777 → rwxrwxrwx  (⚠️ never use on production — world-writable)
400 → r--------  (read-only, SSH private keys)
Enter fullscreen mode Exit fullscreen mode

When a deployment fails with "Permission denied" or a cron job silently does nothing, the first diagnostic is always ls -la to check octal permissions. Developers who understand the octal-to-binary mapping can read the symbolic output (rwxr-xr-x) and the numeric (755) interchangeably — and they fix permission bugs in seconds instead of minutes of trial-and-error.

Two's Complement: How Negative Numbers Work in Binary

Unsigned binary handles only non-negative integers. Real programs need negative numbers. The standard representation for signed integers is two's complement, and understanding it explains several classes of bugs — integer overflow, sign extension errors, and unexpected behavior when mixing signed and unsigned types.

In an 8-bit two's complement system, the most significant bit (MSB) is the sign bit: 0 means positive, 1 means negative. The positive range is 0–127 (0x00–0x7F). The negative range is −128 to −1 (0x80–0xFF).

To negate a number in two's complement: flip all bits, then add 1.

Represent -42 in 8-bit two's complement:

Step 1: Start with 42 in binary
        42 = 00101010

Step 2: Flip all bits (one's complement)
        11010101

Step 3: Add 1
        11010101
      +        1
      ---------
        11010110

Result: 11010110 = -42 in two's complement
Verify: 11010110 → flip → 00101001 → add 1 → 00101010 = 42 ✓
Enter fullscreen mode Exit fullscreen mode

This matters for real bugs. In C, the expression (int8_t)127 + 1 produces -128 — signed integer overflow wraps around. In JavaScript, bitwise operators convert their operands to 32-bit signed integers, which means ~0 is -1 (flip all bits of 0x00000000 → 0xFFFFFFFF → two's complement of -1). If you have ever seen a bitwise NOT produce a negative number and been confused, this is why.

Bitwise Operations: Where Theory Becomes Code

Bitwise operations work directly on the binary representation of integers. They are available in every systems language and in JavaScript/TypeScript via the operators &, |, ^, ~, <<, and >>. The practical applications include feature flags, permission masks, hardware register manipulation, and performance-sensitive data packing.

AND for Masking

The AND operator (&) keeps only the bits that are set in both operands. It is used to extract specific bits from a value — called masking.

// Extract the lower nibble (4 bits) of a byte
const byte = 0xB5       // 10110101
const mask = 0x0F       // 00001111
const lower = byte & mask  // 00000101 = 5

// Check if a permission bit is set
const READ_PERMISSION  = 0b100  // 4
const WRITE_PERMISSION = 0b010  // 2
const EXEC_PERMISSION  = 0b001  // 1

const userPermissions = 0b110  // read + write, no execute

if (userPermissions & READ_PERMISSION) {
  console.log('User can read')
}
if (userPermissions & EXEC_PERMISSION) {
  console.log('User can execute')  // ← this will NOT print
}
Enter fullscreen mode Exit fullscreen mode

OR for Setting Flags

The OR operator (|) sets bits. Use it to add a permission or enable a feature flag.

// Grant execute permission to a user
const newPermissions = userPermissions | EXEC_PERMISSION
// 0b110 | 0b001 = 0b111 = read + write + execute
Enter fullscreen mode Exit fullscreen mode

XOR for Toggling

XOR (^) flips bits that differ. Toggle a flag without knowing its current state:

// Toggle the write permission bit
const toggled = userPermissions ^ WRITE_PERMISSION
// If write was set: removes it. If not set: adds it.
Enter fullscreen mode Exit fullscreen mode

Bit Shifting for Fast Arithmetic

Left shift (<<) multiplies by powers of 2. Right shift (>>) divides by powers of 2. These operations are a single CPU instruction and execute faster than multiplication and division on most architectures.

// Multiply by 8 using left shift
const x = 5
const result = x > 2     // 100 / 4 = 25

// Pack two 8-bit values into a 16-bit integer
const high = 0xAB
const low  = 0xCD
const packed = (high > 8) & 0xFF   // 0xAB
const extractedLow  =  packed       & 0xFF   // 0xCD
Enter fullscreen mode Exit fullscreen mode

The packing pattern is common in network protocols, graphics (packing RGBA channels), and data serialization where you need to combine multiple small values into one integer without a struct.

IP Addresses and Subnet Masks

IPv4 addresses are 32-bit integers displayed as four decimal octets. Understanding this makes subnet calculations trivial instead of mysterious.

IP address:   192.168.1.100
In binary:    11000000.10101000.00000001.01100100

Subnet mask:  255.255.255.0  (a /24 network)
In binary:    11111111.11111111.11111111.00000000

Network addr = IP AND mask:
              11000000.10101000.00000001.00000000
              = 192.168.1.0

Host bits:    The last 8 bits (00000000 to 11111111)
              = 256 addresses (0-255), 254 usable hosts
Enter fullscreen mode Exit fullscreen mode

The CIDR notation /24 means 24 bits are the network prefix — exactly the mask above. /16 means 16 bits (255.255.0.0), /8 means 8 bits (255.0.0.0). Cloud engineers who can mentally calculate subnets in hex save significant time during infrastructure debugging. The binary converter handles IP address to binary conversion as a starting point for these calculations.

Base64: Encoding Binary as Text

Base64 is not a number base in the arithmetic sense, but it follows the same principle — encoding binary data into a character set that is safe for text transport. Base64 groups 6 bits at a time (2⁶ = 64 characters in the alphabet) and is used for encoding binary files in emails, JWT tokens, and data URIs.

A 3-byte (24-bit) sequence becomes four 6-bit groups, each mapped to a printable character. The output is always 4/3 the size of the input (plus padding). Use the base64 encoder/decoder on WOWHOW to inspect JWT payloads, decode image data URIs, or understand what a base64 blob contains.

// Decode a JWT payload (the middle section between the dots)
const payload = 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0'
const decoded = atob(payload)
// {"sub":"1234567890","name":"John Doe"}
Enter fullscreen mode Exit fullscreen mode

Practical Reference: Base Conversion Cheat Sheet

Decimal Binary Octal Hex Use Case
| 0 | 0000 | 0 | 0x0 | Null, off, false |

| 7 | 0111 | 7 | 0x7 | Max single octal digit |

| 8 | 1000 | 10 | 0x8 | First two-digit octal |

| 15 | 1111 | 17 | 0xF | Max single hex digit |

| 16 | 10000 | 20 | 0x10 | First two-digit hex |

| 32 | 100000 | 40 | 0x20 | ASCII space character |

| 127 | 01111111 | 177 | 0x7F | Max signed 8-bit int |

| 128 | 10000000 | 200 | 0x80 | Min signed 8-bit int (−128 in two's complement) |

| 255 | 11111111 | 377 | 0xFF | Max unsigned byte; full RGB channel |

| 256 | 100000000 | 400 | 0x100 | 256 values fit in one byte |

Enter fullscreen mode Exit fullscreen mode




Applying This in Daily Development

Number system knowledge compounds. Once you can read hex memory addresses in a debugger, crash dumps become less intimidating. Once you understand permission bits, chmod and umask become tools you configure deliberately rather than commands you copy from Stack Overflow. Once bitwise operations are comfortable, you write leaner feature flag systems, tighter data serialization, and faster numeric algorithms.

The fastest way to build this fluency is deliberate practice with a tool that gives instant feedback. Open the binary converter, pick a number you know — today's date, a port number, an HTTP status code — and convert it manually, then verify. Do this for five minutes a day for a week. The conversions will become automatic.

For encoding and decoding workflows — JWT payloads, data URIs, image blobs — the base64 encoder/decoder handles the binary-to-text layer. For generating and inspecting hashes, the hash generator shows you the hex output of MD5, SHA-1, SHA-256, and SHA-512 side by side.

Number systems are not something you study once. They are a vocabulary you use every time you configure a server, debug a network issue, optimize a hot loop, or read a memory dump. The developers who internalize them are not just faster — they catch a class of bugs that the rest of the team cannot even see.

Every tool mentioned in this guide is available free at wowhow.cloud/tools — no signup, no install, instant in-browser conversion.

Originally published at wowhow.cloud

Top comments (0)