3.1 Number systems and two’s complement¶
Learning objectives
By the end of this section, you will be able to:
-
Convert between decimal, binary, and hexadecimal number systems
-
Represent negative integers using two’s complement
-
Verify conversions using Python’s built-in functions
Why this matters¶
Computers store everything as bits (0s and 1s). To work effectively with software engineering, we need to understand how computers represent numbers, especially negative values. This knowledge helps when debugging, working with file formats, and understanding data constraints.
Number systems overview¶
Different number systems (or bases) use different sets of digits to represent the same values:
-
Decimal (base 10): Uses digits 0-9
-
Binary (base 2): Uses digits 0-1
-
Hexadecimal (base 16): Uses digits 0-9 and letters A-F
The key principle: each position represents a power of the base.
Decimal example¶
The number 1,347 in decimal means:
-
1 × 10³ + 3 × 10² + 4 × 10¹ + 7 × 10⁰
-
= 1000 + 300 + 40 + 7 = 1,347
Converting between systems¶
Decimal to binary (repeated division)¶
To convert decimal 45 to binary:
-
Divide by 2, note the remainder
-
Continue with the quotient until it reaches 0
-
Read remainders from bottom to top
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
Reading bottom to top: 101101₂
Binary to decimal (positional values)¶
To convert 101101₂ to decimal:
Position: 5 4 3 2 1 0
Digit: 1 0 1 1 0 1
Value: 1×2⁵ + 0×2⁴ + 1×2³ + 1×2² + 0×2¹ + 1×2⁰
= 32 + 0 + 8 + 4 + 0 + 1 = 45
Hexadecimal conversions¶
Hexadecimal is convenient because each hex digit represents exactly 4 binary bits:
| Hex | Binary | Decimal |
|---|---|---|
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| … | … | … |
| 9 | 1001 | 9 |
| A | 1010 | 10 |
| B | 1011 | 11 |
| C | 1100 | 12 |
| D | 1101 | 13 |
| E | 1110 | 14 |
| F | 1111 | 15 |
Example: Convert 101101₂ to hex:
-
Group into 4-bit chunks from right: 0010 1101
-
Convert each chunk: 0010 = 2, 1101 = D
-
Result: 2D₁₆
Two’s complement for negative numbers¶
Two’s complement is how computers represent negative integers. It allows the same arithmetic circuits to handle both positive and negative numbers.
The process¶
To represent a negative number in two’s complement:
-
Start with the positive binary representation
-
Flip all bits (0→1, 1→0) - this is called “one’s complement”
-
Add 1 to the result
Example: -18 in 8-bit two’s complement¶
Start with +18: 00010010
-
Flip all bits:
11101101 -
Add 1:
11101110
So -18 = 11101110 in 8-bit two’s complement.
Understanding the range¶
For N-bit two’s complement:
-
Range: -2ⁿ⁻¹ to +2ⁿ⁻¹-1
-
8-bit range: -128 to +127
-
16-bit range: -32,768 to +32,767
Key insight
The most significant bit (leftmost) indicates the sign: 0 = positive, 1 = negative
Verifying with Python¶
Python provides built-in functions to work with different number systems:
# Converting decimal to other bases
n = 45
print(bin(n)) # Output: 0b101101 (binary)
print(hex(n)) # Output: 0x2d (hexadecimal)
# Converting back to decimal
print(int('101101', 2)) # Output: 45 (from binary)
print(int('2d', 16)) # Output: 45 (from hex)
# Working with negative numbers and two's complement
# Python handles this automatically, but we can see the bit pattern
neg_18 = -18
# Use bitwise AND with 0xFF to see 8-bit representation
eight_bit_pattern = neg_18 & 0xFF
print(bin(eight_bit_pattern)) # Output: 0b11101110
# Verify this matches our manual calculation
manual_calc = 0b11101110
print(f"Manual: {manual_calc}, Python: {eight_bit_pattern}")
print(f"Are they equal? {manual_calc == eight_bit_pattern}")
Practice activity¶
Try these conversions by hand, then verify with Python:
-
Convert decimal 67 to binary
-
Convert binary 1100101₂ to decimal
-
Convert decimal 67 to hexadecimal
-
Find the 8-bit two’s complement representation of -25
Solutions:
-
67₁₀ = 1000011₂
-
1100101₂ = 101₁₀
-
67₁₀ = 43₁₆
-
-25 = 11100111₂ (8-bit two’s complement)
Summary¶
-
Binary, decimal, and hexadecimal are different ways to write the same values
-
Conversion methods: repeated division (to binary), positional values (from binary), grouping by 4s (binary ↔ hex)
-
Two’s complement represents negative integers by flipping bits and adding 1
-
Python functions:
bin(),hex(),int()help verify manual calculations
Understanding these number systems is essential for working with computer memory, file formats, and debugging low-level issues in software engineering.