Theory: Bits, Bytes & Positional Number Conversions
Everything a computer stores (numbers, text, pictures, instructions) is ultimately a pattern of bits. Before we can understand how a CPU adds, compares or stores numbers, we need to be fluent at moving between the number systems humans like (decimal) and the ones hardware likes (binary, and its shorthands octal and hexadecimal). This page builds that fluency from scratch (Null & Lobur, Ch. 2).
Bits, Nibbles, Bytes and Words
Unit
Size
Notes
Bit (binary digit)
1 bit
The most basic unit of information: 0 or 1. Physically a state of a circuit: “off/on”, “low/high voltage”.
Nibble
4 bits
Half a byte. Exactly one hexadecimal digit.
Byte
8 bits
The smallest addressable unit in most machines (byte-addressable memory). Two hex digits.
Word
a contiguous group of bytes
Machine dependent; 16, 32 and 64 bits are most common. The “natural” size the CPU processes at once.
Byte-addressable vs word-addressable memory. An address names one storage location.
In a byte-addressable system every byte has its own address, so a 32-bit word occupies 4 consecutive addresses.
In a word-addressable system the word is the smallest addressable unit: each address names a whole word, and individual bytes inside it cannot be addressed directly.
The number of address bits needed is log2(number of addressable units).
Mini-example
A memory holds 224 bytes and uses 32-bit (4-byte) words.
Byte-addressable: 224 addresses, so 24 address bits.
Word-addressable: 224/22=222 words, so 22 address bits.
Positional Numbering Systems
In a positional (weighted) number system with base (or radix) b, each digit is multiplied by a power of b that depends on its position. Positions to the left of the radix point have weights b0,b1,b2,… (from right to left); positions to the right have weights b−1,b−2,…
(dn−1⋯d1d0.d−1d−2⋯)b=i∑di×bi,0≤di≤b−1
A base-b system uses exactly b distinct digit symbols, 0 to b−1.
Base
Name
Digits
2
binary
0, 1
8
octal
0–7
10
decimal
0–9
16
hexadecimal
0–9, A(10), B(11), C(12), D(13), E(14), F(15)
Any integer quantity can be represented exactly in any base. The two most important radices in computer science are binary (what the hardware uses) and hexadecimal (a compact, human-readable shorthand for binary).
Find the largest power bk that is ≤ the number (use k=⌊logbN⌋).
See how many times bk fits (that count is the digit for position k, between 0 and b−1); subtract.
Repeat with bk−1,…,b0. Every power down to b0 gets a digit, even if it is 0.
Method 2: Division-remainder (the one used most in practice).
Divide the number by b. Write down the remainder (it is a digit, 0 to b−1).
Replace the number by the quotient and repeat until the quotient is 0.
Read the remainders from bottom to top (the first remainder is the least significant digit).
Mini-example (division-remainder, 10410 to base 3)
Division
Quotient
Remainder
104÷3
34
2 (LSD)
34÷3
11
1
11÷3
3
2
3÷3
1
0
1÷3
0
1 (MSD)
Reading bottom to top: 10410=102123.
Why does it work? Dividing by b peels off the last base-b digit as the remainder, exactly like dividing a decimal number by 10 gives its last digit as the remainder (241÷10=24 r 1).
Converting Decimal Fractions → Base b (Repeated Multiplication)
For the part after the radix point, use the target radix as a multiplier:
Multiply the fraction by b.
The integer part of the product is the next digit (going left to right after the point).
Keep only the fractional part and repeat.
Stop when the fractional part becomes 0, or when you have produced the required number of digits.
Read the digits from top to bottom (the first digit produced is the one right after the point).
For a mixed number (like 2.8125), convert the integer part by division-remainder and the fraction by repeated multiplication, then join them.
Mini-example (0.812510 to binary)
Step
Multiply
Product
Digit
1
0.8125×2
1.6250
1
2
0.6250×2
1.2500
1
3
0.2500×2
0.5000
0
4
0.5000×2
1.0000
1 (fraction is now 0, stop)
Top to bottom: 0.812510=0.11012. Since 210=102, we get 2.812510=10.11012.
Non-terminating fractions. A decimal fraction terminates in base 2 only if, in lowest terms, its denominator is a power of 2. Something as innocent as 0.110 becomes the repeating pattern 0.000112=0.000110011001…2, so it cannot be stored exactly in any finite number of bits. You must stop after a fixed number of bits, which introduces a (small) error. This is one root cause of floating-point errors (section 2.5).
Binary ↔ Hexadecimal ↔ Octal (Grouping)
Because 16=24 and 8=23, every hex digit corresponds to exactly 4 bits and every octal digit to exactly 3 bits. No arithmetic is needed, just grouping.
Binary → hex (or octal):
Starting at the radix point, split the bits into groups of 4 (for hex) or 3 (for octal): moving left for the integer part and right for the fraction part.
Pad the outermost groups with zeros (leading zeros on the left, trailing zeros on the right of the fraction).
Replace each group by its digit.
Hex (or octal) → binary: replace each digit by its 4-bit (or 3-bit) pattern.
Hex ↔ octal: go through binary.
Hex
Binary
Hex
Binary
Hex
Binary
Hex
Binary
0
0000
4
0100
8
1000
C
1100
1
0001
5
0101
9
1001
D
1101
2
0010
6
0110
A
1010
E
1110
3
0011
7
0111
B
1011
F
1111
Mini-example
101111102=BE16,101111102=0101111102=2768
Check: BE16=11×16+14=190 and 2768=2×64+7×8+6=190 ✓.
How Many Digits? (Logarithms)
With n base-b digits you can write bn different values, 0 to bn−1. So n bits hold unsigned values 0 to 2n−1.
The highest power of b needed for a number N is k=⌊logbN⌋ (this is the place to start the subtraction method).
The number of digits needed is ⌊logbN⌋+1.
On a calculator, logbN=lnblnN=log10blog10N.
Mini-example
log3104=ln3ln104≈4.228, so the highest power is 34=81 and 104 needs 4+1=5 base-3 digits (indeed 102123 has 5 digits).
Worked Examples
Exercise 1
Convert 00110101000110112 to hexadecimal, octal and decimal.
Show solution ↓Hide solution ↑
Solution
Hexadecimal: group into 4s from the right.
0011010100011011→351B
So 00110101000110112=351B16.
Octal: group into 3s from the right. 16 bits do not divide evenly into 3s, so pad the leftmost group with leading zeros:
→0000011010100011011→032433
So the value is 324338.
Decimal: expand the hex form (fewer terms than expanding 16 bits):
(a) Convert 14710 to binary using division-remainder, then write it in hexadecimal and octal.
(b) Convert 2.812510 and 13.37510 to binary.
Show solution ↓Hide solution ↑
Solution
(a) Divide repeatedly by 2:
Division
Quotient
Remainder
147÷2
73
1
73÷2
36
1
36÷2
18
0
18÷2
9
0
9÷2
4
1
4÷2
2
0
2÷2
1
0
1÷2
0
1
Bottom to top: 14710=100100112.
Hex: 10010011→9316 (check: 9×16+3=147 ✓).
Octal: 010010011→2238 (check: 2×64+2×8+3=147 ✓).
(b) Split each number into integer and fraction parts.
2.8125: integer 2=102. Fraction 0.8125:
Multiply
Product
Digit
0.8125×2
1.625
1
0.625×2
1.25
1
0.25×2
0.5
0
0.5×2
1.0
1
So 2.812510=10.11012. Check: 2+0.5+0.25+0.0625=2.8125 ✓.
13.375: integer 13=11012 (13÷2=6 r 1, 6÷2=3 r 0, 3÷2=1 r 1, 1÷2=0 r 1). Fraction 0.375:
Multiply
Product
Digit
0.375×2
0.75
0
0.75×2
1.5
1
0.5×2
1.0
1
So 13.37510=1101.0112. Check: 8+4+1+0.25+0.125=13.375 ✓.
Exercise 5
Convert 0.110 and 0.610 to binary, keeping 8 bits after the binary point. Do the conversions terminate? What decimal value does each 8-bit result actually represent?
Show solution ↓Hide solution ↑
Solution
0.110:
Step
Multiply
Product
Digit
1
0.1×2
0.2
0
2
0.2×2
0.4
0
3
0.4×2
0.8
0
4
0.8×2
1.6
1
5
0.6×2
1.2
1
6
0.2×2
0.4
0
7
0.4×2
0.8
0
8
0.8×2
1.6
1
At step 6 the fraction 0.2 has appeared before (after step 1), so the pattern repeats forever: 0.110=0.000112=0.000110011001…2. It never terminates.
Kept to 8 bits: 0.000110012=25625=0.09765625. The error is 0.1−0.09765625=0.00234375.
0.610:
Step
Multiply
Product
Digit
1
0.6×2
1.2
1
2
0.2×2
0.4
0
3
0.4×2
0.8
0
4
0.8×2
1.6
1
5
0.6×2
1.2
1
6
0.2×2
0.4
0
7
0.4×2
0.8
0
8
0.8×2
1.6
1
The fraction 0.6 returns at step 5, so 0.610=0.10012, also non-terminating.
Kept to 8 bits: 0.100110012=256153=0.59765625.
Both fail to terminate because 0.1=101 and 0.6=53 have a factor 5 in the denominator, which is not a power of 2. By contrast 0.8125=1613 and 0.375=83 terminate.
Exercise 6
Convert 7A9.C16 to binary and to octal. Verify by converting both to decimal.
Grouping always starts at the radix point. Grouping the fraction from the right-hand end (e.g. turning .11 into .011=.38) gives the wrong answer.
Exercise 7
(a) How many bits are needed to represent 100010 in unsigned binary?
(b) What is the highest power of 3 needed to write 10410 in base 3, and how many base-3 digits does it have?
(c) What range of unsigned values fits in 12 bits? How many hex digits does a 16-bit word take?
(d) A machine has 224 bytes of memory and 32-bit words. How many address bits are needed if memory is (i) byte-addressable, (ii) word-addressable?
Show solution ↓Hide solution ↑
Solution
(a)log21000≈9.97, so the highest power is 29=512 and the number of bits is ⌊9.97⌋+1=10. Check: 29=512≤1000<1024=210, so 9 bits (max 511) are too few and 10 bits (max 1023) suffice. Indeed 100010=11111010002 (10 bits).
(b)log3104=ln3ln104≈1.0994.644≈4.228. The highest power is 3⌊4.228⌋=34=81, and the number of digits is 4+1=5 (matches 102123).
(c) 12 bits give 212=4096 patterns: unsigned values 0 to 4095. A 16-bit word is 16/4=4 hex digits (each hex digit = one nibble).
(d)
(i) Byte-addressable: one address per byte, 224 addresses → 24 bits.
(ii) Word-addressable: each 32-bit word is 4 bytes =22 bytes, so there are 224/22=222 words → 22 bits.