BeyondIT logo
BeyondIT
DSA Fundamentals #2 : From Bits to Bytes Understand the Number Systems
Technology

DSA Fundamentals #2 : From Bits to Bytes Understand the Number Systems

17 min read
#Technology
Table Of Content

Part I: The Foundations of Digital Numeracy

Understanding Positional Number Systems

The Core Concept: Base and Positional Value

A number system is a language for writing numbers. These languages use a set of symbols, or digits. Two rules govern these systems: the base and positional notation.

The base, or radix, is the number of unique digits the system uses. This count includes the digit zero.

  • Our common decimal system is base-10. It uses ten digits (0 through 9).

  • The binary system is base-2. It uses two digits (0 and 1).

Positional notation means a digit’s value depends on its location in a number. In the number 555, each '5' has a different value. There is a '5' in the hundreds place, a '5' in the tens place, and a '5' in the ones place. The value of each position is the base raised to a power. This differs from Roman numerals, where 'X' always means ten.

Deconstructing Decimal (Base-10): Our Everyday System

The decimal system is the base-10 system we use daily. Each position represents a power of 10. Let's examine the number 2003:

(2×10^3)+(0×10^2)+(0×10^1)+(3×10^0)=2000+0+0+3=2003

Understanding this structure is the key to learning other number systems.

Introducing Binary (Base-2): The Language of Computers

The binary system is the language of modern computers. It is a base-2 system and uses only two digits: 0 and 1. These digits are called bits. In binary, each position represents a power of 2.

For example, we can convert the binary number 1011​ to decimal:

(1×2^3)+(0×2^2)+(1×2^1)+(1×2^0)=8+0+2+1=11

Introducing Hexadecimal (Base-16): The Programmer's Shorthand

The hexadecimal system, or "hex," is a base-16 system. Programmers use it to write long binary numbers in a shorter form. It uses 16 symbols: the digits 0 through 9 and the letters A, B, C, D, E, and F. The letters represent the values 10 through 15. Each position in a hex number represents a power of 16.

For example, let's convert the hex number 1A3 to decimal:

(1×16^2)+(10×16^1)+(3×16^0)=256+160+3=419

Pro Tip: We use subscripts like 10110​ to show the base. We can also use prefixes like 0x for hexadecimal (0x1A3) and 0b for binary (0bx1011).

Why Binary and Hexadecimal Are Fundamental to Computing

Why do computers use binary? The answer lies in their hardware.

A computer contains billions of tiny electronic switches called transistors. Each switch has only two possible states: ON or OFF. The binary system, with its two digits 1 (ON) and 0 (OFF), perfectly matches this physical design. This makes binary the natural language for computers.

The main problem with binary is that the numbers get very long. A single byte of data is eight bits long, such as 11010101. A memory address can be 64 bits long. Reading or typing these long strings of 0s and 1s often leads to mistakes.

Hexadecimal solves this problem. It works as a shorthand for binary because of a simple relationship: 16=24. This means a group of four binary digits, called a nibble, corresponds to exactly one hexadecimal digit.

For example, the byte 11010101 splits into two nibbles: 1101 and 0101.

  • 1101 in binary is 13 in decimal, which is D in hex.

  • 0101 in binary is 5 in decimal, which is 5 in hex.

So, the long binary number 11010101 becomes the short hex number D5.

Binary is the language of the machine. Hexadecimal is the convenient shorthand for the programmer.

Table 1: Number System Comparison

This chart helps show the patterns between the systems.

DecimalBinaryHexadecimal
000
111
2102
3113
41004
51015
61106
71117
810008
910019
101010A
111011B
121100C
131101D
141110E
151111F
161000010
171000111
181001012
191001113
201010014

Section 2: Core Conversion Techniques

Converting from Any Base to Decimal

This basic method converts a number from any base to the decimal system.

  1. Find the positional value for each digit. This is the base raised to the power of its position, starting from 0 on the right.

  2. Multiply each digit by its positional value.

  3. Add all the results.

Example (Binary to Decimal): Convert 1101.12​ to decimal.

The positions are 3, 2, 1, and 0 for the whole number part, and -1 for the fractional part.

Calculation: (1×23)+(1×22)+(0×21)+(1×20)+(1×2-1)

Sum: 8+4+0+1+0.5=13.510​

Example (Hexadecimal to Decimal): Convert A4E16​ to decimal.

Remember that A=10 and E=14.

Calculation: (10×162)+(4×161)+(14×160)

Sum: (10×256)+(4×16)+(14×1)=2560+64+14=263810

Converting from Decimal to Any Base

To convert from decimal to another base, we use a different method with two parts.

For the Whole Number Part (Repeated Division):

  1. Divide the decimal number by the target base.

  2. Write down the remainder. This is a digit for your new number.

  3. Take the quotient from the division and repeat the process.

  4. Continue until the quotient is 0.

  5. Read the remainders in reverse order (bottom to top) to get the final answer.

For the Fractional Part (Repeated Multiplication):

  1. Multiply the decimal fraction by the target base.

  2. The whole number part of the result is the first digit of your new fraction.

  3. Take the fractional part of the result and repeat the process.

  4. Continue until the fraction becomes 0 or you have enough digits.

  5. Read the whole numbers in the order you recorded them to get the final answer.

Example: Convert 25.62510​ to binary.

Whole Number (25):

  • 25÷2=12 Remainder 1

  • 12÷2=6 Remainder 0

  • 6÷2=3 Remainder 0

  • 3÷2=1 Remainder 1

  • 1÷2=0 Remainder 1

Reading in reverse gives 110012​.

Fractional Part (0.625):

  • 0.625×2=1.25 Record the whole number: 1

  • 0.25×2=0.5 Record the whole number: 0

  • 0.5×2=1.0 Record the whole number: 1

Reading in order gives .1012​.

Final Answer: 11001.1012

The Binary-Hexadecimal Shortcut: Grouping by Fours

Programmers use this fast trick often. You can convert between binary and hex without using decimal.

Binary to Hexadecimal:

  1. Split the binary number into groups of four bits (nibbles), starting from the decimal point.

  2. If the leftmost group has fewer than four bits, add zeros to the front.

  3. Convert each 4-bit group to its single hex digit.

Hexadecimal to Binary:

  1. Take each hex digit.

  2. Convert it to its 4-bit binary equivalent.

  3. Combine the binary groups.

A programmer sees 1101 0101 and thinks D5, which is much simpler.

Table 2: Binary-to-Hexadecimal Nibble Conversion

This table is the key to using the shortcut.

4-Bit Binary (Nibble)Decimal ValueHexadecimal Digit
000000
000111
001022
001133
010044
010155
011066
011177
100088
100199
101010A
101111B
110012C
110113D
111014E
111115F

Part II: Advanced Data Representation

Section 3: Representing Signed Integers

The Challenge of Representing Negative Numbers

How do you write a negative number with only 0s and 1s? One idea is to use a single bit to represent the sign. For instance, 0 for positive and 1 for negative. This is called sign-and-magnitude. This system has problems. It creates two ways to write zero (+0 and -0). It also complicates the math for computer hardware.

Two's Complement: The Universal Standard

Modern computers use a system called two's complement to represent positive and negative integers. In this system, the first bit (the most significant bit, or MSB) indicates the sign. A 0 means positive, and a 1 means negative. The MSB also has a negative value. For an 8-bit number, the MSB has a value of -128.

For example, in an 8-bit system, we calculate the number 11100100 like this:

(−1×128)+(1×64)+(1×32)+(0×16)+(0×8)+(1×4)+(0×2)+(0×1)

=−128+64+32+4=−28

The Negation Algorithm: Finding the Opposite

Two's complement makes it easy to change a number's sign, like turning 5 into -5.

The "Flip and Add One" Recipe:

  1. Invert all the bits. Change every 0 to a 1, and every 1 to a 0. This is the ones' complement.

  2. Add 1 to the result. Ignore any extra carry bit at the end.

Example: Find the 8-bit two's complement for -69.

  1. Start with positive 69 in binary: 01000101.

  2. Invert all the bits: 10111010.

  3. Add 1: 10111010 + 1 = 10111011.

So, -69 is stored as 10111011.

Arithmetic in Two's Complement

The main benefit of two's complement is that it simplifies computer math. The computer can use the same hardware circuit for both addition and subtraction. To subtract B from A, the computer calculates A + (the two's complement of B).

Example (Subtraction): Calculate 57 - 28. The computer performs this as 57 + (-28).

  • 57 in 8-bit binary is 00111001.

  • -28 in 8-bit two's complement is 11100100.

Now, add them:

  00111001   (57)
+ 11100100   (-28)
------------------
1 00011101   (29)

We ignore the extra carry bit on the left. The 8-bit answer is 00011101, which is 29.

Two's Complement as a Hardware-Level Optimization

This math trick is important for processor design. The part of the processor that performs math is the Arithmetic Logic Unit (ALU). Building separate circuits for addition and subtraction would make the ALU larger and use more power.

With two's complement, the computer needs only one circuit: an adder. To subtract, the computer uses NOT gates to flip the bits of the second number. Then it uses the adder to add 1 and perform the final addition. A single circuit does both operations, making processors smaller and faster.

Section 4: Representing Real Numbers

The Challenge: Representing Fractions and Scientific Notation

We have discussed whole numbers. What about numbers with fractions, like 3.14, or very large numbers? We need a system that can "float" the decimal point.

IEEE 754: The Global Standard

The IEEE 754 standard is a universal rulebook for floating-point numbers. It defines how to store them, so all computers calculate them the same way.

Anatomy of an IEEE 754 Number

An IEEE 754 number has three parts, similar to scientific notation: (−1)sign×1.fraction×2exponent.

  • Sign Bit (1 bit): This is simple. 0 is for positive, and 1 is for negative.

  • Biased Exponent (8 or 11 bits): The exponent shows how far to move the decimal point. The standard adds a fixed number, or bias, to the real exponent. This allows the storage of positive and negative exponents without a separate sign bit. For a 32-bit number, the bias is 127. The computer stores Real Exponent + 127.

  • Mantissa (23 or 52 bits): This part stores the number's actual digits. In binary scientific notation, a number always starts with 1.something.... The standard does not store the leading 1. This is the "hidden bit" trick, which saves space and adds precision.

Single-Precision (32-bit) vs. Double-Precision (64-bit)

There are two common sizes for floating-point numbers:

  • Single-Precision (float): A 32-bit number with 1 sign bit, 8 exponent bits, and 23 mantissa bits. It is good for general use.

  • Double-Precision (double): A 64-bit number with 1 sign bit, 11 exponent bits, and 52 mantissa bits. It stores a wider range of numbers with much higher precision.

Special Values: Handling Edge Cases

The IEEE 754 standard defines special patterns for unusual values:

  • Zero: An exponent of all zeros and a mantissa of all zeros.

  • Infinity: An exponent of all ones and a mantissa of all zeros.

  • NaN (Not a Number): An exponent of all ones and a non-zero mantissa. This results from invalid operations like 0÷0.

  • Denormalized Numbers: These are very small numbers near zero. The "hidden bit" is assumed to be 0 instead of 1. This allows a gradual loss of precision.

The Trade-off Between Range and Precision

Floating-point numbers are an engineering compromise. The bits are split between the exponent (range) and the mantissa (precision). This allows the representation of an enormous range of values.

But there is a catch: the precision is not uniform.

  • For small numbers near zero, the representable values are close together. Precision is high.

  • For huge numbers, the representable values are far apart. The gap between them can be large.

This is why 0.1 + 0.2 does not exactly equal 0.3 in many programming languages. The numbers 0.1 and 0.2 cannot be represented perfectly in binary. They are rounded to the nearest available floating-point value. The sum of these rounded values is not the same as the rounded value of 0.3. We sacrifice uniform precision to get the massive range needed for science and computing.

Part III: Manipulation and Application

Section 5: Bitwise Operations

Definition

Bitwise operations work on numbers at the bit level. They treat the number 13 as the bit string 1101. These operations are fast because they map directly to processor instructions.

Logical Operations

These operations apply Boolean logic to each pair of bits.

Table 3: Bitwise Operator Truth Tables

pqp & q (AND)p | q (OR)p ^ q (XOR)
00000
01011
10011
11110
  • AND (&): Gives a 1 only if both bits are 1.

    • Main Use (Masking/Clearing): Checks if a specific bit is on or turns a bit off. To check the 3rd bit, you can AND the number with 00001000. If the result is not zero, the bit was on.
  • OR (|): Gives a 1 if either bit is 1.

    • Main Use (Setting): Turns a specific bit on. To turn on the 3rd bit, you can OR the number with 00001000. This does not change other bits.
  • XOR (^): Gives a 1 only if the bits are different.

    • Main Use (Toggling): Flips a bit. To flip the 3rd bit, you can XOR your number with 00001000.
  • NOT (~): Flips every bit in a single number. This is also called the ones' complement.

Shift Operations

Shift operations slide all bits in a number to the left or right.

  • Left Shift (<< n): Slides all bits n places to the left. Zeros fill in on the right. This is a fast way to multiply a number by 2n.

  • Right Shift (>> n): Slides all bits n places to the right. This is a fast way to do integer division by 2n. What fills in on the left depends on the type of shift:

    • Arithmetic Right Shift: Used for signed numbers. It copies the original sign bit to preserve the number's sign.

    • Logical Right Shift: Used for unsigned numbers. It always fills the empty spots with zeros.

Practical Application: Bitmasking

Bitmasking is a common programming technique. You can use the bits of a single integer to store a set of flags instead of using many separate true/false variables. This saves memory.

Example: File Permissions

Operating systems use bitmasking for file permissions. Let's say bit 2 is Read, bit 1 is Write, and bit 0 is Execute.

  • READ_PERMISSION = 4 (binary 100)

  • WRITE_PERMISSION = 2 (binary 010)

  • EXECUTE_PERMISSION = 1 (binary 001)

A file that is readable and writable has permissions READ_PERMISSION | WRITE_PERMISSION, which is 4 | 2 = 6 (binary 110).

  • To check for write permission: if (permissions & WRITE_PERMISSION)

  • To add execute permission: permissions = permissions | EXECUTE_PERMISSION

  • To remove write permission: permissions = permissions & ~WRITE_PERMISSION

This technique is common in low-level programming where speed and memory are important.

Section 6: Number Systems in the Real World

Memory, Debugging, and Data Representation

  • Memory Addressing: Every byte in a computer's memory has a unique address. These addresses are written in hexadecimal because it is shorter and easier to read than binary. An address like 0x7FFD80792F7C is easier to read than 64 ones and zeros.

  • Debugging: Programmers look at "memory dumps" to find bugs. These snapshots of memory are displayed in hex for quick scanning.

  • Character Encoding:

    • ASCII: An early character set for English. It used 7 or 8 bits, which allowed for only 128 or 256 characters.

    • Unicode and UTF-8: Unicode is a standard that gives a unique number, or code point, to every character. UTF-8 is the most popular way to encode Unicode numbers into binary. It uses one byte for ASCII characters and up to four bytes for other characters.

Table 4: Common Character Encodings

CharacterDecimalASCII (7-bit binary)Unicode Code PointUTF-8 (binary)
A651000001U+004101000001
$360100100U+002400100100
N/ANot in ASCIIU+20AC11100010 10000010 10101100
öN/ANot in ASCIIU+00F611000011 10110110
👍N/ANot in ASCIIU+1F44D11110000 10011111 10010001 10001101

Networking: IP Addressing

  • IPv4: An IPv4 address is a 32-bit number. We write it as four decimal numbers separated by dots, like 192.168.1.1. Each number is an 8-bit segment called an octet.

  • IPv6: The world ran out of IPv4 addresses. The new standard is IPv6, which uses 128-bit numbers. They are written as eight groups of four hexadecimal digits, separated by colons, like 2001:0db8:85a3:0000:0000:8a2e:0370:7334.

  • Subnet Masks: A subnet mask tells a router which part of an IP address identifies the network and which part identifies the computer. It uses a bitwise AND operation between the IP address and the mask.

Web Development: CSS Hex Color Codes

A color on a website defined as #FF0000 is a hexadecimal color code. The format is #RRGGBB.

  • RR is the amount of Red.

  • GG is the amount of Green.

  • BB is the amount of Blue.

Each value is a two-digit hex number from 00 (none) to FF (maximum). For example, #FF0000 is pure red, and #FFFFFF is white.

Hardware: Digital Logic Circuits

All computer hardware is built from logic gates (AND, OR, NOT gates). These are tiny electronic circuits that perform bitwise operations. A high voltage signal is a 1, and a low voltage signal is a 0. When a computer performs math, it is flipping switches according to the rules of logic.

Part IV: Tools and Practice for Mastery

Section 7: Modern Tools for Exploration

Using Python for Number Systems

Python is a good tool for experimenting with these concepts.

  • bin(x): Converts an integer to a binary string. bin(13) gives '0b1101'.

  • hex(x): Converts an integer to a hex string. hex(26) gives '0x1a'.

  • int(s, base): Converts a string s in a given base to an integer. int('1a', 16) gives 26.

Python also supports all bitwise operators: &, |, ^, ~, <<, >>.

# --- Conversions ---
decimal_val = 173
binary_str = bin(decimal_val)      # Result: '0b10101101'
hex_str = hex(decimal_val)          # Result: '0xad'

# Convert back to decimal
binary_to_dec = int('10101101', 2) # Result: 173
hex_to_dec = int('ad', 16)          # Result: 173

# --- Bitwise Operations ---
a = 92  # Binary: 01011100
b = 101 # Binary: 01100101

# Bitwise AND: checks which bits are 1 in BOTH numbers
print(f"a & b = {a & b}") # Result: 68 (binary 01000100)

# Bitwise OR: checks which bits are 1 in EITHER number
print(f"a | b = {a | b}") # Result: 125 (binary 01111101)

# Bitwise XOR: checks which bits are DIFFERENT
print(f"a ^ b = {a ^ b}") # Result: 57 (binary 00111001)

# Bitwise NOT: flips all the bits of 'a'
print(f"~a = {~a}") # Result: -93 (due to two's complement)

# Bit Shifts: fast multiplication and division by 2
print(f"a << 2 = {a << 2}") # Result: 368 (92 * 4)
print(f"a >> 2 = {a >> 2}") # Result: 23 (92 // 4)

Specialized Python Libraries

  • SymPy: A library for symbolic math with a module for logic.

  • Mathesis: A library for learning formal logic.

  • pylogics: A library for representing different kinds of logic.

Online Calculators and Simulators

  • Stanford Introduction to Logic: This site has a Digital Circuit Builder and a tool for truth tables called Boole.

  • LogicTools.org: An online tool that solves logic formulas and generates truth tables.

Section 8: Comprehensive Practice Problems

Number System Conversions

  • Binary to Decimal: Convert 110112​ to decimal.

    • Solution: (1×16)+(1×8)+(0×4)+(1×2)+(1×1)=16+8+2+1=2710​.
  • Decimal to Hexadecimal: Convert 45210​ to hexadecimal.

    • Solution: 452÷16=28 R 4. 28÷16=1 R 12 (C). 1÷16=0 R 1. Reading remainders in reverse gives 1C416​.
  • Hexadecimal to Binary: Convert DE016​ to binary.

    • Solution: D = 1101, E = 1110, 0 = 0000. Combining gives 1101111000002​.

Two's Complement Arithmetic

  • Negation: Find the 8-bit two's complement of -42.

    • Solution: Positive 42 is 00101010. Invert bits: 11010101. Add 1: 110101102​.
  • Subtraction: Calculate 35 - 50 using 8-bit two's complement.

    • Solution: This is 35 + (-50). 35 is 00100011. -50 is 11001110.

    • 00100011 + 11001110 = 11110001.

    • The result is negative. To find its magnitude, take its two's complement. Invert (00001110) and add 1 (00001111), which is 15. The answer is −1510​.

Bitwise Operations

  • Set a bit: Given the number 77 (01001101_2), set the 6th bit.

    • Solution: The mask is 1 << 6, which is 01000000_2.

    • 01001101 | 01000000 = 01001101. The bit was already set.

  • Clear a bit: Given the number 77 (01001101_2), clear the 2nd bit.

    • Solution: The mask is ~(1 << 2), which is 11111011_2.

    • 01001101 & 11111011 = 01001001, which is 73.

  • Count set bits: How many set bits are in the number 203 (11001011_2)?

    • Solution: Using Brian Kernighan's algorithm, the answer is 5.

Section 9: Capstone Project Ideas

  • Build a universal number system converter.

  • Create a bitwise operations calculator.

  • Write a program to encode a text message into a hex string.

  • Build an IPv4 subnet calculator.

  • Create a visualizer for IEEE 754 floating-point numbers.

Appendix: Further Learning Resources

  • Stanford University - Introduction to Logic (Coursera)

  • University of Leeds - An Introduction to Logic for Computer Science (Coursera)

  • Ahmed Muhammed - Number Systems For Beginners (Udemy)

  • Khan Academy: Offers videos and exercises on binary and hexadecimal systems.

  • For Discrete Mathematics and Logic:

    • Discrete Mathematics and Its Applications by Kenneth H. Rosen

    • Discrete Mathematics with Applications by Susanna S. Epp

  • For Computer Architecture:

    • Computer Organization & Design by David A. Patterson and John L. Hennessy

    • Computer Systems: A Programmer's Perspective by Randal E. Bryant and David R. O'Hallaron

    • Code: The Hidden Language of Computer Hardware and Software by Charles Petzold

Final Thoughts

Understanding decimal, binary, and hexadecimal is a core skill for computing. Binary is the computer's native language. Hexadecimal is the programmer's shorthand for it. Concepts like two's complement and IEEE 754 make computer math possible. Learning these languages and tools gives you a deep understanding of how the digital world is built.