Master

What the machine holds underneath

A value is stored as bits, and the kind says how to read them. That is why a whole number and a decimal number are not the same thing, and why a very big count can stop working.

What you will see

17

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Measure the rounding and avoid it for money.

1

See the rounding directly.

print(0.1 + 0.2)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0.30000000000000004
2

Prove exact equality fails on it.

print(0.1 + 0.2 == 0.3)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
False
3

Test closeness instead, with a tiny allowed distance.

print(abs((0.1 + 0.2) - 0.3) < 1e-9)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
True
4

Do the same sum in whole cents and it is exact.

print(12 + 5)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
17
Whole numbers are exact, decimals are not. That is the reason currency, counts of items, and time in milliseconds are usually kept as whole numbers.

Data Flow

The value is stored as bits, the kind says how to read them, and a decimal that has no exact binary form is rounded to the nearest one.
1 0.1 is stored as bits
↓
2 the bits are a fraction
↓
3 no exact tenth exists
↓
4 the sum prints the rounding
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

print(0.1 + 0.2) 0.30000000000000004
Why this works
Why the kinds exist at all

The machine has only bits. The kind is the instruction for reading them: as a whole number, as a fraction, as characters. Two values can be the same bits read two ways, which is where the confusion between 4 and "4" comes from.

The size question

Whole numbers in this language grow as needed, so a huge count is fine. Decimal numbers have a fixed number of bits, so they carry a fixed precision and a limit. Knowing which kind you hold tells you which of the two worries applies.

Examples

Bits are the truth

print((1024).bit_length())
print((1025).bit_length())

A whole number is stored as its binary digits, so the count of digits grows with the size. 1024 needs eleven bits, 1025 still needs eleven. The machine counts in bits, not in your decimal digits.

Decimals are approximations

print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)

The sum prints 0.30000000000000004 and the comparison says no. A decimal number is stored as a binary fraction, and a tenth has no exact binary fraction, so it is rounded.

Compare the safe way

print(abs((0.1 + 0.2) - 0.3) < 1e-9)

Asking whether two decimals are close, within a tiny distance, is the honest test. Exact equality on decimals is only correct when both sides came from the same computation.

Money is not decimals

cents = 1250
print(cents / 100)

Store money as whole cents and divide only when showing it. That keeps every sum exact, which is why real systems avoid decimal numbers for currency.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Names and values are separate things
Previous Lesson
Names and values are separate things
Next Lesson
Text is numbers too
Text is numbers too →