---
title: 'Binary Number System'
source: 'https://academia.sh/en/courses/how-computers-work/binary-number-system'
course: 'How Computers Work'
language: en
updated: '2026-08-17T18:08:07+00:00'
license: 'CC BY-SA 4.0'
---

# Binary Number System

Positional number systems, binary representation, and conversion between bases.

Everything that resides in a computer's memory — this lesson text, a photograph, the
running program itself — is an object of the same kind: a sequence of two-state
switches. This lesson asks the following question: how are numbers written in a medium
that can hold nothing but two states?

The answer turns out to be a special case of a more general rule that already governs
the number system used in daily life. Before turning to the binary system, it is worth
looking carefully at what the decimal system actually does.

## Positional Value

When `4703` is written in the decimal system, four separate symbols are placed side by
side, but the value expressed is not the sum of those symbols. Each symbol's
contribution depends on its position:

$$
4703 = 4 \times 10^3 + 7 \times 10^2 + 0 \times 10^1 + 3 \times 10^0
$$

This scheme is called **positional notation**. It has three components: a **base** $b$,
$b$ **digits** running from $0$ to $b-1$, and exponents that increase from right to
left. In general, a number with digits $d_{n-1} d_{n-2} \dots d_1 d_0$ has the value:

$$
\sum_{i=0}^{n-1} d_i \times b^{i}
$$

The decimal system has nothing special about it; the base being ten is a historical
consequence of having ten fingers on two hands. The rule works identically for every
base. When the base is reduced to two, the digit set narrows to $\{0, 1\}$ — which
corresponds directly to two-state hardware.

## Binary Representation

In the **binary** system the base is $2$ and the digits are $0$ and $1$. A single
binary digit is called a **bit**, a word that abbreviates "binary digit." Positional
values are powers of two:

$$
1011_2 = 1 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 1 \times 2^0 = 8 + 0 + 2 + 1 = 11
$$

The subscript states which base the number is written in. This marker is necessary:
the sequence `1011` reads as one thousand eleven if taken as decimal, and as eleven if
taken as binary. The fact that the same symbol sequence carries different values in
different bases will appear in a sharper form in later lessons — the same bit sequence
can be a number, a letter, or an instruction, depending on who interprets it.

The first ten binary numbers, with their counterparts:

| Decimal | Binary | Decimal | Binary |
|---|---|---|---|
| 0 | 0 | 5 | 101 |
| 1 | 1 | 6 | 110 |
| 2 | 10 | 7 | 111 |
| 3 | 11 | 8 | 1000 |
| 4 | 100 | 9 | 1001 |

A pattern stands out: every time the number reaches a power of two, one more digit
becomes necessary. The same thing that happens when decimal moves from `9` to `10`
happens in binary when moving from `1` to `10`.

## Binary to Decimal

Converting a binary number to decimal is a direct application of the definition: sum
the positional values of the bits. It suffices to add the positional values of the
bits equal to $1$, since bits equal to $0$ contribute nothing.

$$
110101_2 = 32 + 16 + 4 + 1 = 53
$$

Here the positional values from right to left are $1, 2, 4, 8, 16, 32$; the bits equal
to $1$ sit at positions $0$, $2$, $4$, and $5$.

## Decimal to Binary

The opposite direction uses repeated division. Divide the number by two, record the
remainder, continue with the quotient; once the quotient reaches zero, read the
remainders in **reverse order**.

For $53$:

| Division | Quotient | Remainder |
|---|---|---|
| $53 \div 2$ | 26 | 1 |
| $26 \div 2$ | 13 | 0 |
| $13 \div 2$ | 6 | 1 |
| $6 \div 2$ | 3 | 0 |
| $3 \div 2$ | 1 | 1 |
| $1 \div 2$ | 0 | 1 |

Reading the remainders from bottom to top yields $110101_2$, consistent with the value
computed in the previous section.

Why the method works becomes clear from the definition of positional value. The
remainder of dividing a number by two is that number's rightmost bit: even numbers end
in $0$, odd numbers end in $1$. Taking the quotient shifts the number one digit to the
right, and the same question is then asked for the next bit.

## Bits, Bytes, and Value Count

A single bit distinguishes two states. Two bits distinguish four, three bits
distinguish eight. In general, $n$ bits can write

$$
2^n
$$

distinct patterns. This is the upper bound on representational capacity, and it is a
counting fact independent of hardware: 8 bits allow 256 distinct patterns, and there
is no 257th pattern.

A group of eight bits is called a **byte**. A byte is the smallest addressable unit of
memory; the processor reads at least a whole byte, never a single bit. When
interpreted as an unsigned integer, a byte holds values between $0$ and $255$: the
smallest pattern is `00000000`, the largest is `11111111`, that is,
$2^8 - 1 = 255$.

More generally, an $n$-bit unsigned integer ranges between $0$ and $2^n - 1$. The $-1$
arises because zero itself spends one pattern. Common widths and their bounds:

| Width | Pattern count | Largest unsigned value |
|---|---|---|
| 8 bit | 256 | 255 |
| 16 bit | 65,536 | 65,535 |
| 32 bit | 4,294,967,296 | 4,294,967,295 |
| 64 bit | $\approx 1{.}8 \times 10^{19}$ | $2^{64} - 1$ |

This table holds a bound that later lessons will return to often. A variable's width
determines the largest value it can hold; once that bound is exceeded, the number does
not grow — its representation breaks. Overflow behavior will be detailed in the lesson
on signed integers.

## Seeing the Conversion in Code

The following program carries out the two conversions performed by hand in this
lesson and compares the results against the built-in functions.

```python
def decimal_to_binary(number: int) -> str:
    """Returns the binary representation of a non-negative integer."""
    if number == 0:
        return "0"
    bits = []
    while number > 0:
        bits.append(str(number % 2))   # remainder: rightmost bit
        number //= 2                   # quotient: shift one digit right
    return "".join(reversed(bits))


def binary_to_decimal(representation: str) -> int:
    """Decodes a binary representation by summing positional values."""
    value = 0
    for bit in representation:
        value = value * 2 + int(bit)
    return value


print(decimal_to_binary(53))          # 110101
print(binary_to_decimal("110101"))    # 53
print(bin(53), int("110101", 2))      # 0b110101 53
```

The line `value = value * 2 + int(bit)` inside `binary_to_decimal` is the left-to-right
reading of the positional-value definition: each new bit shifts the value accumulated
so far one digit to the left and adds its own contribution.

Python's built-in `bin` function returns the binary representation with a `0b` prefix;
the second parameter of the `int` function specifies which base to read. This prefix is
only a notational convention, not part of the number itself.

## Summary

- In positional notation, a digit's contribution is determined by the base raised to
  its position; the decimal system carries no special privilege.
- In the binary system the base is $2$ and the digit set is $\{0, 1\}$; a single
  binary digit is called a bit.
- Converting binary to decimal means summing the positional values of the bits equal
  to $1$; the reverse direction means reading the remainders of repeated division in
  reverse order.
- With $n$ bits, exactly $2^n$ distinct patterns can be written; under an unsigned
  interpretation the largest value is $2^n - 1$.
- A group of eight bits is called a byte, and memory is addressed at the byte level.

## Next Step

Binary representation stays faithful to the hardware, but it is inconvenient for the
human eye: a single 32-bit value is a sequence of zeros and ones that is hard to read
without error. The next lesson takes up the hexadecimal base, which writes the same
bit pattern with fewer symbols without breaking bit boundaries; that lesson will also
establish a concrete example that the course will return to repeatedly.
