Number base conversion is one of the most fundamental skills in computer science. Whether you're debugging low-level code, working with memory addresses, or analyzing network packets, understanding different number systems is essential. This comprehensive guide covers the theory, algorithms, and practical implementations of base conversion.

Understanding Number Systems

What is a Number Base?

A number base (or radix) defines how many unique digits are used to represent numbers. The base determines the positional value of each digit.

Base Name Digits Used Common Use
2 Binary 0, 1 Computer hardware, bit operations
8 Octal 0-7 Unix file permissions
10 Decimal 0-9 Daily life, human counting
16 Hexadecimal 0-9, A-F Memory addresses, color codes

Positional Notation

In any base system, a number's value is calculated by:

code
Value = Σ (digit × base^position)

For example, the decimal number 1234:

code
1234₁₀ = 1×10³ + 2×10² + 3×10¹ + 4×10⁰
       = 1000 + 200 + 30 + 4
       = 1234

Binary Number System (Base 2)

Why Binary Matters

Computers use binary because electronic circuits have two stable states: on (1) and off (0). Every piece of data in a computer—from text to images to programs—is ultimately represented in binary.

Binary to Decimal Conversion

To convert binary to decimal, multiply each bit by its positional power of 2:

code
10110₂ = 1×2⁴ + 0×2³ + 1×2² + 1×2¹ + 0×2⁰
       = 16 + 0 + 4 + 2 + 0
       = 22₁₀

Decimal to Binary Conversion

Use the repeated division method:

code
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

Reading remainders bottom-up: 10110₂

Binary Arithmetic

Addition:

code
  1011  (11)
+ 0110  (6)
------
 10001  (17)

Rules: 0+0=0, 0+1=1, 1+0=1, 1+1=10 (carry 1)

Subtraction using Two's Complement:

code
To subtract A - B:
1. Find two's complement of B (invert bits, add 1)
2. Add A + two's complement of B

Hexadecimal Number System (Base 16)

Hexadecimal Digits

Decimal Hex Binary
0-9 0-9 0000-1001
10 A 1010
11 B 1011
12 C 1100
13 D 1101
14 E 1110
15 F 1111

Why Hexadecimal?

Hexadecimal is popular because:

  1. Compact representation: One hex digit = 4 binary bits
  2. Easy conversion: Direct mapping to binary
  3. Human readable: Shorter than binary, more intuitive than decimal for byte values

Hexadecimal to Decimal

code
2AF₁₆ = 2×16² + 10×16¹ + 15×16⁰
      = 512 + 160 + 15
      = 687₁₀

Hexadecimal to Binary

Convert each hex digit to 4 binary bits:

code
2AF₁₆ = 0010 1010 1111₂
        2    A    F

Common Hexadecimal Uses

Memory Addresses:

code
0x7fff5fbff8c0  // Stack address
0x100000000     // Common base address

Color Codes:

css
#FF5733  /* RGB: 255, 87, 51 */
#00FF00  /* Pure green */

MAC Addresses:

code
00:1A:2B:3C:4D:5E

Octal Number System (Base 8)

Octal Basics

Octal uses digits 0-7. Each octal digit represents 3 binary bits.

Unix File Permissions

The most common use of octal is Unix file permissions:

bash
chmod 755 file.sh

Breaking down 755:

  • 7 (111₂) = rwx (read, write, execute) for owner
  • 5 (101₂) = r-x (read, execute) for group
  • 5 (101₂) = r-x (read, execute) for others

Octal Conversion

Octal to Binary:

code
752₈ = 111 101 010₂
       7   5   2

Octal to Decimal:

code
752₈ = 7×8² + 5×8¹ + 2×8⁰
     = 448 + 40 + 2
     = 490₁₀

Conversion Algorithms

Universal Conversion Method

To convert from any base to any other base:

  1. Convert source to decimal (intermediate)
  2. Convert decimal to target base

Direct Binary-Hex Conversion

Since 16 = 2⁴, conversion is direct:

Binary → Hex: Group bits in fours from right

code
1101 0110 1011₂ = D6B₁₆

Hex → Binary: Expand each hex digit to 4 bits

code
A3F₁₆ = 1010 0011 1111₂

Direct Binary-Octal Conversion

Since 8 = 2³, group bits in threes:

Binary → Octal:

code
101 110 011₂ = 563₈

Octal → Binary:

code
274₈ = 010 111 100₂

Code Implementations

JavaScript Implementation

javascript
class BaseConverter {
  static toDecimal(value, fromBase) {
    return parseInt(value, fromBase);
  }

  static fromDecimal(decimal, toBase) {
    return decimal.toString(toBase).toUpperCase();
  }

  static convert(value, fromBase, toBase) {
    const decimal = this.toDecimal(value, fromBase);
    return this.fromDecimal(decimal, toBase);
  }

  static toBinary(value, fromBase = 10) {
    return this.convert(value, fromBase, 2);
  }

  static toHex(value, fromBase = 10) {
    return this.convert(value, fromBase, 16);
  }

  static toOctal(value, fromBase = 10) {
    return this.convert(value, fromBase, 8);
  }
}

// Usage examples
console.log(BaseConverter.convert('FF', 16, 10));  // "255"
console.log(BaseConverter.convert('255', 10, 2));  // "11111111"
console.log(BaseConverter.toBinary('A5', 16));     // "10100101"

Python Implementation

python
class BaseConverter:
    @staticmethod
    def to_decimal(value: str, from_base: int) -> int:
        return int(value, from_base)
    
    @staticmethod
    def from_decimal(decimal: int, to_base: int) -> str:
        if to_base == 2:
            return bin(decimal)[2:]
        elif to_base == 8:
            return oct(decimal)[2:]
        elif to_base == 16:
            return hex(decimal)[2:].upper()
        else:
            # Generic conversion for any base
            if decimal == 0:
                return '0'
            digits = []
            while decimal:
                digits.append('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'[decimal % to_base])
                decimal //= to_base
            return ''.join(reversed(digits))
    
    @staticmethod
    def convert(value: str, from_base: int, to_base: int) -> str:
        decimal = BaseConverter.to_decimal(value, from_base)
        return BaseConverter.from_decimal(decimal, to_base)

# Usage examples
print(BaseConverter.convert('FF', 16, 10))   # 255
print(BaseConverter.convert('255', 10, 2))   # 11111111
print(BaseConverter.convert('777', 8, 16))   # 1FF

Java Implementation

java
public class BaseConverter {
    public static long toDecimal(String value, int fromBase) {
        return Long.parseLong(value, fromBase);
    }
    
    public static String fromDecimal(long decimal, int toBase) {
        return Long.toString(decimal, toBase).toUpperCase();
    }
    
    public static String convert(String value, int fromBase, int toBase) {
        long decimal = toDecimal(value, fromBase);
        return fromDecimal(decimal, toBase);
    }
    
    public static void main(String[] args) {
        System.out.println(convert("FF", 16, 10));   // 255
        System.out.println(convert("255", 10, 2));   // 11111111
        System.out.println(convert("1010", 2, 16));  // A
    }
}

Go Implementation

go
package main

import (
    "fmt"
    "strconv"
    "strings"
)

func ToDecimal(value string, fromBase int) (int64, error) {
    return strconv.ParseInt(value, fromBase, 64)
}

func FromDecimal(decimal int64, toBase int) string {
    return strings.ToUpper(strconv.FormatInt(decimal, toBase))
}

func Convert(value string, fromBase, toBase int) (string, error) {
    decimal, err := ToDecimal(value, fromBase)
    if err != nil {
        return "", err
    }
    return FromDecimal(decimal, toBase), nil
}

func main() {
    result, _ := Convert("FF", 16, 10)
    fmt.Println(result)  // 255
    
    result, _ = Convert("255", 10, 2)
    fmt.Println(result)  // 11111111
}

Practical Applications

1. Bit Manipulation

javascript
// Check if nth bit is set
function isBitSet(num, n) {
  return (num & (1 << n)) !== 0;
}

// Set nth bit
function setBit(num, n) {
  return num | (1 << n);
}

// Clear nth bit
function clearBit(num, n) {
  return num & ~(1 << n);
}

// Toggle nth bit
function toggleBit(num, n) {
  return num ^ (1 << n);
}

2. IP Address Conversion

python
def ip_to_binary(ip):
    """Convert IP address to binary representation"""
    octets = ip.split('.')
    binary_octets = [format(int(octet), '08b') for octet in octets]
    return '.'.join(binary_octets)

def ip_to_decimal(ip):
    """Convert IP address to single decimal number"""
    octets = [int(x) for x in ip.split('.')]
    return (octets[0] << 24) + (octets[1] << 16) + (octets[2] << 8) + octets[3]

# Example
print(ip_to_binary('192.168.1.1'))
# 11000000.10101000.00000001.00000001

print(ip_to_decimal('192.168.1.1'))
# 3232235777

3. Color Code Conversion

javascript
function hexToRgb(hex) {
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result ? {
    r: parseInt(result[1], 16),
    g: parseInt(result[2], 16),
    b: parseInt(result[3], 16)
  } : null;
}

function rgbToHex(r, g, b) {
  return '#' + [r, g, b]
    .map(x => x.toString(16).padStart(2, '0'))
    .join('')
    .toUpperCase();
}

console.log(hexToRgb('#FF5733'));  // {r: 255, g: 87, b: 51}
console.log(rgbToHex(255, 87, 51)); // #FF5733

4. Unicode and Character Encoding

python
def char_to_codes(char):
    """Get various representations of a character"""
    code_point = ord(char)
    return {
        'character': char,
        'decimal': code_point,
        'hexadecimal': hex(code_point),
        'binary': bin(code_point),
        'octal': oct(code_point)
    }

print(char_to_codes('A'))
# {'character': 'A', 'decimal': 65, 'hexadecimal': '0x41', 
#  'binary': '0b1000001', 'octal': '0o101'}

Common Pitfalls and Solutions

1. Leading Zeros

javascript
// Problem: Leading zeros in octal
const num = 010;  // This is 8 in decimal (octal literal)!

// Solution: Use explicit conversion
const num = parseInt('010', 10);  // 10 in decimal

2. Large Number Precision

javascript
// Problem: JavaScript loses precision for large integers
const big = 0x1FFFFFFFFFFFFF;  // Max safe integer

// Solution: Use BigInt for large numbers
const bigNum = BigInt('0x1FFFFFFFFFFFFFF');
console.log(bigNum.toString(2));  // Accurate binary

3. Negative Numbers

python
# Two's complement representation
def twos_complement(n, bits=8):
    """Get two's complement representation"""
    if n < 0:
        n = (1 << bits) + n
    return format(n, f'0{bits}b')

print(twos_complement(-5, 8))   # 11111011
print(twos_complement(5, 8))    # 00000101

Quick Reference Table

Decimal Binary Octal Hexadecimal
0 0000 0 0
1 0001 1 1
2 0010 2 2
3 0011 3 3
4 0100 4 4
5 0101 5 5
6 0110 6 6
7 0111 7 7
8 1000 10 8
9 1001 11 9
10 1010 12 A
11 1011 13 B
12 1100 14 C
13 1101 15 D
14 1110 16 E
15 1111 17 F
16 10000 20 10
255 11111111 377 FF

Summary

Number base conversion is a fundamental skill for programmers. Key takeaways:

  1. Binary (base 2) is the foundation of all computer operations
  2. Hexadecimal (base 16) provides compact representation of binary data
  3. Octal (base 8) is primarily used for Unix file permissions
  4. Direct conversion between binary, octal, and hex is efficient due to power-of-2 relationships
  5. Understanding two's complement is essential for working with negative numbers

For quick and accurate base conversions, try our Base Converter Tool - it supports conversions between binary, octal, decimal, and hexadecimal with real-time results.