About

2.1 Bits, Bytes & Positional Number Conversions

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

UnitSizeNotes
Bit (binary digit)1 bitThe most basic unit of information: 00 or 11. Physically a state of a circuit: “off/on”, “low/high voltage”.
Nibble4 bitsHalf a byte. Exactly one hexadecimal digit.
Byte8 bitsThe smallest addressable unit in most machines (byte-addressable memory). Two hex digits.
Worda contiguous group of bytesMachine 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.

The number of address bits needed is log⁡2(number of addressable units)\log_2(\text{number of addressable units}).

Mini-example

A memory holds 2242^{24} bytes and uses 32-bit (4-byte) words.

Positional Numbering Systems

In a positional (weighted) number system with base (or radix) bb, each digit is multiplied by a power of bb that depends on its position. Positions to the left of the radix point have weights b0,b1,b2,…b^0, b^1, b^2, \dots (from right to left); positions to the right have weights b−1,b−2,…b^{-1}, b^{-2}, \dots

(dn−1⋯d1d0 . d−1d−2⋯ )b=∑idi×b i,0≤di≤b−1(d_{n-1} \cdots d_1 d_0 \,.\, d_{-1} d_{-2} \cdots)_b = \sum_{i} d_i \times b^{\,i}, \qquad 0 \le d_i \le b-1

A base-bb system uses exactly bb distinct digit symbols, 00 to b−1b-1.

BaseNameDigits
2binary0, 1
8octal0–7
10decimal0–9
16hexadecimal0–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).

Mini-example

24110=2×102+4×101+1×100,10012=1×23+0×22+0×21+1×20=910241_{10} = 2 \times 10^2 + 4 \times 10^1 + 1 \times 10^0, \qquad 1001_2 = 1 \times 2^3 + 0 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 = 9_{10}

Converting Any Base → Decimal (Expansion)

Procedure: write each digit times its positional weight and add everything up in decimal. This works for fractional digits too (negative powers).

Mini-example

102123=1(81)+0(27)+2(9)+1(3)+2(1)=81+0+18+3+2=1041010212_3 = 1(81) + 0(27) + 2(9) + 1(3) + 2(1) = 81 + 0 + 18 + 3 + 2 = 104_{10} 101.112=4+0+1+12+14=5.7510101.11_2 = 4 + 0 + 1 + \tfrac12 + \tfrac14 = 5.75_{10}

Converting Decimal → Base bb (Whole Numbers)

There are two equivalent methods.

Method 1: Subtraction (of powers).

  1. Find the largest power bkb^k that is ≤\le the number (use k=⌊log⁡bN⌋k = \lfloor \log_b N \rfloor).
  2. See how many times bkb^k fits (that count is the digit for position kk, between 00 and b−1b-1); subtract.
  3. Repeat with bk−1,…,b0b^{k-1}, \dots, b^0. Every power down to b0b^0 gets a digit, even if it is 00.

Method 2: Division-remainder (the one used most in practice).

  1. Divide the number by bb. Write down the remainder (it is a digit, 00 to b−1b-1).
  2. Replace the number by the quotient and repeat until the quotient is 00.
  3. Read the remainders from bottom to top (the first remainder is the least significant digit).

Mini-example (division-remainder, 10410104_{10} to base 3)

DivisionQuotientRemainder
104÷3104 \div 3342 (LSD)
34÷334 \div 3111
11÷311 \div 332
3÷33 \div 310
1÷31 \div 301 (MSD)

Reading bottom to top: 10410=102123104_{10} = 10212_3.

Why does it work? Dividing by bb peels off the last base-bb digit as the remainder, exactly like dividing a decimal number by 10 gives its last digit as the remainder (241÷10=24241 \div 10 = 24 r 11).

Converting Decimal Fractions → Base bb (Repeated Multiplication)

For the part after the radix point, use the target radix as a multiplier:

  1. Multiply the fraction by bb.
  2. The integer part of the product is the next digit (going left to right after the point).
  3. Keep only the fractional part and repeat.
  4. Stop when the fractional part becomes 0, or when you have produced the required number of digits.
  5. Read the digits from top to bottom (the first digit produced is the one right after the point).

For a mixed number (like 2.81252.8125), convert the integer part by division-remainder and the fraction by repeated multiplication, then join them.

Mini-example (0.8125100.8125_{10} to binary)

StepMultiplyProductDigit
10.8125×20.8125 \times 21.62501
20.6250×20.6250 \times 21.25001
30.2500×20.2500 \times 20.50000
40.5000×20.5000 \times 21.00001 (fraction is now 0, stop)

Top to bottom: 0.812510=0.110120.8125_{10} = 0.1101_2. Since 210=1022_{10} = 10_2, we get 2.812510=10.110122.8125_{10} = 10.1101_2.

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.1100.1_{10} becomes the repeating pattern 0.00011‾2=0.000110011001…20.0\overline{0011}_2 = 0.000110011001\ldots_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=2416 = 2^4 and 8=238 = 2^3, 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):

  1. 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.
  2. Pad the outermost groups with zeros (leading zeros on the left, trailing zeros on the right of the fraction).
  3. 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.

HexBinaryHexBinaryHexBinaryHexBinary
000004010081000C1100
100015010191001D1101
2001060110A1010E1110
3001170111B1011F1111

Mini-example

1011 11102=BE16,10 111 1102=010 111 1102=27681011\,1110_2 = \text{BE}_{16}, \qquad 10\,111\,110_2 = 010\,111\,110_2 = 276_8

Check: BE16=11×16+14=190\text{BE}_{16} = 11 \times 16 + 14 = 190 and 2768=2×64+7×8+6=190276_8 = 2 \times 64 + 7 \times 8 + 6 = 190 ✓.

How Many Digits? (Logarithms)

Mini-example

log⁡3104=ln⁡104ln⁡3≈4.228\log_3 104 = \dfrac{\ln 104}{\ln 3} \approx 4.228, so the highest power is 34=813^4 = 81 and 104104 needs 4+1=54 + 1 = 5 base-3 digits (indeed 10212310212_3 has 5 digits).


Worked Examples

Exercise 1

Convert 001101010001101120011010100011011_2 to hexadecimal, octal and decimal.

Show solution ↓
Solution

Hexadecimal: group into 4s from the right.

0011 0101 0001 1011  →  3  5  1  B0011\ 0101\ 0001\ 1011 \;\to\; 3\ \ 5\ \ 1\ \ \text{B}

So 00110101000110112=351B160011010100011011_2 = \text{351B}_{16}.

Octal: group into 3s from the right. 16 bits do not divide evenly into 3s, so pad the leftmost group with leading zeros:

0⏟→ 000 011 010 100 011 011  →  0 3 2 4 3 3\underbrace{0}_{\to\, 000}\ 011\ 010\ 100\ 011\ 011 \;\to\; 0\ 3\ 2\ 4\ 3\ 3

So the value is 32433832433_8.

Decimal: expand the hex form (fewer terms than expanding 16 bits):

351B16=3×163+5×162+1×16+11=12288+1280+16+11=1359510\text{351B}_{16} = 3 \times 16^3 + 5 \times 16^2 + 1 \times 16 + 11 = 12288 + 1280 + 16 + 11 = 13595_{10}

Check via octal: 3×84+2×83+4×82+3×8+3=12288+1024+256+24+3=135953 \times 8^4 + 2 \times 8^3 + 4 \times 8^2 + 3 \times 8 + 3 = 12288 + 1024 + 256 + 24 + 3 = 13595 ✓.

Exercise 2

Convert each number to decimal.

(a) 2A316\text{2A3}_{16} (b) 123451234_5 (c) 1011.10121011.101_2 (d) 3D.816\text{3D.8}_{16}

Show solution ↓
Solution

Multiply each digit by its positional weight and add.

(a) 2A316=2×256+10×16+3×1=512+160+3=67510\text{2A3}_{16} = 2 \times 256 + 10 \times 16 + 3 \times 1 = 512 + 160 + 3 = 675_{10}

(b) 12345=1×125+2×25+3×5+4×1=125+50+15+4=194101234_5 = 1 \times 125 + 2 \times 25 + 3 \times 5 + 4 \times 1 = 125 + 50 + 15 + 4 = 194_{10}

(c) Integer part 10112=8+0+2+1=111011_2 = 8 + 0 + 2 + 1 = 11. Fraction part:

.1012=1×2−1+0×2−2+1×2−3=0.5+0+0.125=0.625.101_2 = 1 \times 2^{-1} + 0 \times 2^{-2} + 1 \times 2^{-3} = 0.5 + 0 + 0.125 = 0.625

So 1011.1012=11.625101011.101_2 = 11.625_{10}.

(d) 3D.816=3×16+13×1+8×16−1=48+13+0.5=61.510\text{3D.8}_{16} = 3 \times 16 + 13 \times 1 + 8 \times 16^{-1} = 48 + 13 + 0.5 = 61.5_{10}

Exercise 3

Convert 10410104_{10} to base 3 using (a) the subtraction method and (b) the division-remainder method. Verify your answer.

Show solution ↓
Solution

(a) Subtraction. Powers of 3: 30=1,31=3,32=9,33=27,34=81,35=2433^0 = 1, 3^1 = 3, 3^2 = 9, 3^3 = 27, 3^4 = 81, 3^5 = 243. The largest power ≤104\le 104 is 34=813^4 = 81 (also ⌊log⁡3104⌋=⌊4.228⌋=4\lfloor \log_3 104 \rfloor = \lfloor 4.228 \rfloor = 4).

PowerHow many fitSubtractRemaining
34=813^4 = 811104−81104 - 8123
33=273^3 = 27023−023 - 023
32=93^2 = 9223−1823 - 185
31=33^1 = 315−35 - 32
30=13^0 = 122−22 - 20

Digits top to bottom: 10212310212_3.

(b) Division-remainder.

DivisionQuotientRemainder
104÷3104 \div 3342
34÷334 \div 3111
11÷311 \div 332
3÷33 \div 310
1÷31 \div 301

Remainders bottom to top: 10212310212_3. Both methods agree.

Verify: 1(81)+0(27)+2(9)+1(3)+2(1)=81+18+3+2=1041(81) + 0(27) + 2(9) + 1(3) + 2(1) = 81 + 18 + 3 + 2 = 104 ✓.

Exercise 4

(a) Convert 14710147_{10} to binary using division-remainder, then write it in hexadecimal and octal.

(b) Convert 2.8125102.8125_{10} and 13.3751013.375_{10} to binary.

Show solution ↓
Solution

(a) Divide repeatedly by 2:

DivisionQuotientRemainder
147÷2147 \div 2731
73÷273 \div 2361
36÷236 \div 2180
18÷218 \div 290
9÷29 \div 241
4÷24 \div 220
2÷22 \div 210
1÷21 \div 201

Bottom to top: 14710=100100112147_{10} = 10010011_2.

  • Hex: 1001 0011→93161001\ 0011 \to 93_{16} (check: 9×16+3=1479 \times 16 + 3 = 147 ✓).
  • Octal: 010 010 011→2238010\ 010\ 011 \to 223_8 (check: 2×64+2×8+3=1472 \times 64 + 2 \times 8 + 3 = 147 ✓).

(b) Split each number into integer and fraction parts.

2.81252.8125: integer 2=1022 = 10_2. Fraction 0.81250.8125:

MultiplyProductDigit
0.8125×20.8125 \times 21.6251
0.625×20.625 \times 21.251
0.25×20.25 \times 20.50
0.5×20.5 \times 21.01

So 2.812510=10.110122.8125_{10} = 10.1101_2. Check: 2+0.5+0.25+0.0625=2.81252 + 0.5 + 0.25 + 0.0625 = 2.8125 ✓.

13.37513.375: integer 13=1101213 = 1101_2 (13÷2=613 \div 2 = 6 r 1, 6÷2=36 \div 2 = 3 r 0, 3÷2=13 \div 2 = 1 r 1, 1÷2=01 \div 2 = 0 r 1). Fraction 0.3750.375:

MultiplyProductDigit
0.375×20.375 \times 20.750
0.75×20.75 \times 21.51
0.5×20.5 \times 21.01

So 13.37510=1101.011213.375_{10} = 1101.011_2. Check: 8+4+1+0.25+0.125=13.3758 + 4 + 1 + 0.25 + 0.125 = 13.375 ✓.

Exercise 5

Convert 0.1100.1_{10} and 0.6100.6_{10} 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 ↓
Solution

0.1100.1_{10}:

StepMultiplyProductDigit
10.1×20.1 \times 20.20
20.2×20.2 \times 20.40
30.4×20.4 \times 20.80
40.8×20.8 \times 21.61
50.6×20.6 \times 21.21
60.2×20.2 \times 20.40
70.4×20.4 \times 20.80
80.8×20.8 \times 21.61

At step 6 the fraction 0.20.2 has appeared before (after step 1), so the pattern repeats forever: 0.110=0.00011‾2=0.000110011001…20.1_{10} = 0.0\overline{0011}_2 = 0.000110011001\ldots_2. It never terminates.

Kept to 8 bits: 0.000110012=25256=0.097656250.00011001_2 = \dfrac{25}{256} = 0.09765625. The error is 0.1−0.09765625=0.002343750.1 - 0.09765625 = 0.00234375.

0.6100.6_{10}:

StepMultiplyProductDigit
10.6×20.6 \times 21.21
20.2×20.2 \times 20.40
30.4×20.4 \times 20.80
40.8×20.8 \times 21.61
50.6×20.6 \times 21.21
60.2×20.2 \times 20.40
70.4×20.4 \times 20.80
80.8×20.8 \times 21.61

The fraction 0.60.6 returns at step 5, so 0.610=0.1001‾20.6_{10} = 0.\overline{1001}_2, also non-terminating.

Kept to 8 bits: 0.100110012=153256=0.597656250.10011001_2 = \dfrac{153}{256} = 0.59765625.

Both fail to terminate because 0.1=1100.1 = \tfrac{1}{10} and 0.6=350.6 = \tfrac{3}{5} have a factor 5 in the denominator, which is not a power of 2. By contrast 0.8125=13160.8125 = \tfrac{13}{16} and 0.375=380.375 = \tfrac{3}{8} terminate.

Exercise 6

Convert 7A9.C16\text{7A9.C}_{16} to binary and to octal. Verify by converting both to decimal.

Show solution ↓
Solution

Hex → binary: replace each hex digit by 4 bits.

7→0111,A→1010,9→1001,C→11007 \to 0111,\quad \text{A} \to 1010,\quad 9 \to 1001,\quad \text{C} \to 11007A9.C16=0111 1010 1001.11002=11110101001.112\text{7A9.C}_{16} = 0111\,1010\,1001.1100_2 = 11110101001.11_2

(drop the leading 0 and the trailing 0s).

Binary → octal: regroup in 3s outward from the point. Integer part, from the right: 11 110 101 001→011 110 101 00111\,110\,101\,001 \to 011\,110\,101\,001. Fraction part, from the left: .11→.110.11 \to .110.

011 110 101 001 . 110  →  3 6 5 1 . 6011\ 110\ 101\ 001\ .\ 110 \;\to\; 3\ 6\ 5\ 1\ .\ 6

So 7A9.C16=3651.68\text{7A9.C}_{16} = 3651.6_8.

Verify:

7A9.C16=7(256)+10(16)+9+12/16=1792+160+9+0.75=1961.75\text{7A9.C}_{16} = 7(256) + 10(16) + 9 + 12/16 = 1792 + 160 + 9 + 0.75 = 1961.753651.68=3(512)+6(64)+5(8)+1+6/8=1536+384+40+1+0.75=1961.75 ✓3651.6_8 = 3(512) + 6(64) + 5(8) + 1 + 6/8 = 1536 + 384 + 40 + 1 + 0.75 = 1961.75 \ ✓

Grouping always starts at the radix point. Grouping the fraction from the right-hand end (e.g. turning .11.11 into .011=.38.011 = .3_8) gives the wrong answer.

Exercise 7

(a) How many bits are needed to represent 1000101000_{10} in unsigned binary?

(b) What is the highest power of 3 needed to write 10410104_{10} 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 2242^{24} bytes of memory and 32-bit words. How many address bits are needed if memory is (i) byte-addressable, (ii) word-addressable?

Show solution ↓
Solution

(a) log⁡21000≈9.97\log_2 1000 \approx 9.97, so the highest power is 29=5122^9 = 512 and the number of bits is ⌊9.97⌋+1=10\lfloor 9.97 \rfloor + 1 = 10. Check: 29=512≤1000<1024=2102^9 = 512 \le 1000 \lt 1024 = 2^{10}, so 9 bits (max 511) are too few and 10 bits (max 1023) suffice. Indeed 100010=111110100021000_{10} = 1111101000_2 (10 bits).

(b) log⁡3104=ln⁡104ln⁡3≈4.6441.099≈4.228\log_3 104 = \dfrac{\ln 104}{\ln 3} \approx \dfrac{4.644}{1.099} \approx 4.228. The highest power is 3⌊4.228⌋=34=813^{\lfloor 4.228 \rfloor} = 3^4 = 81, and the number of digits is 4+1=54 + 1 = 5 (matches 10212310212_3).

(c) 12 bits give 212=40962^{12} = 4096 patterns: unsigned values 00 to 40954095. A 16-bit word is 16/4=416 / 4 = 4 hex digits (each hex digit = one nibble).

(d)

  • (i) Byte-addressable: one address per byte, 2242^{24} addresses → 24 bits.
  • (ii) Word-addressable: each 32-bit word is 4 bytes =22= 2^2 bytes, so there are 224/22=2222^{24}/2^2 = 2^{22} words → 22 bits.