Addaly is in open beta. Things will change, and AI answers can be wrong — check anything that matters.

Python, From Zero, For AI

From your first line of code to your first API call.

Lesson 5 of 898 min

Numbers: whole, decimal, and the one that surprises everybody

Two kinds of number, and five operators

Python has whole numbers (int) and decimals (float).

python
>>> 7 + 2      # 9
>>> 7 - 2      # 5
>>> 7 * 2      # 14
>>> 7 / 2      # 3.5
>>> 7 // 2     # 3
>>> 7 % 2      # 1
>>> 7 ** 2     # 49

Three of those deserve attention.

/ always gives a float, even when it divides evenly. 10 / 5 is 2.0, not 2. This differs from most other languages and from Python 2, so old code and old tutorials get it wrong.

// is floor division — it rounds down, towards minus infinity, not towards zero. So 7 // 2 is 3, and -7 // 2 is -4, not -3. If you expected -3 you were thinking of truncation. This shows up when splitting negative quantities and it is genuinely confusing the first time.

% is the remainder, and it is more useful than it looks: n % 2 == 0 tests for even, n % 100 gives the last two digits, and seconds % 60 gives the seconds part of a duration.

Integers in Python have no size limit. 2 ** 1000 computes a 302-digit number without complaint, because Python stores big integers in as many chunks as they need. Most languages would overflow. It is slower than fixed-size arithmetic, and you will never notice unless you are doing cryptography.

The float surprise

Type this:

python
>>> 0.1 + 0.2
0.30000000000000004

Python is not broken and this is not a bug in your machine. A float is a 64-bit IEEE 754 number: a sign, an exponent, and 53 bits of mantissa. Those bits store a value in binary, and 0.1 in binary is a recurring fraction, exactly the way 1/3 is recurring in decimal. It gets stored as the nearest representable value, which is very slightly off. Add two of those and the error becomes visible at the seventeenth digit.

What Python actually does with 0.1 + 0.20.1 in yourfileA decimal youtyped, in basetenNearest double0.1000000000000000055…,the closest ofthe values 53bits can holdThe two areaddedThe exact sum ofthe two storedvalues, not of0.1 and 0.2Rounded again0.30000000000000004,because the sumhas no exactdouble either== 0.3 is False0.3 stores as adifferentdouble. Usemath.iscloseNothing here is a bug and nothing is Python's. Every language using 64-bit IEEE 754 doubles doesexactly this, including JavaScript, Java and your spreadsheet. The consequences to live with: nevercompare computed floats with ==, round only for display, and store money as whole paise in an int.
What Python actually does with 0.1 + 0.20.1 in your fileA decimal you typed, in base tenNearest double0.1000000000000000055…, the closest of thevalues 53 bits can holdThe two are addedThe exact sum of the two stored values, not of0.1 and 0.2Rounded again0.30000000000000004, because the sum has noexact double either== 0.3 is False0.3 stores as a different double. Usemath.iscloseNothing here is a bug and nothing is Python's. Everylanguage using 64-bit IEEE 754 doubles does exactlythis, including JavaScript, Java and yourspreadsheet. The consequences to live with: nevercompare computed floats with ==, round only fordisplay, and store money as whole paise in an int.

Three consequences you have to live with:

  1. Never compare floats with ==. 0.1 + 0.2 == 0.3 is False. Use math.isclose(a, b) instead, which allows a tiny tolerance.
  2. Round only for display. round(value, 2) gives you something to print. Keep the full value for further arithmetic, or you will round repeatedly and drift.
  3. Never store money as a float. Store paise, cents or the smallest unit as integers, or use decimal.Decimal("19.99"), which does base-10 arithmetic and is exact. Financial code that adds thousands of floats and compares the total against a bank statement will eventually be off by a paisa, and finding out why costs a day.

Rounding is not what you were taught

python
>>> round(2.5)
2
>>> round(3.5)
4

That is not a mistake. Python uses banker's rounding: exact halves go to the nearest even number. Rounding 0.5 always up biases a long column of numbers upwards, and over a million rows that bias is measurable. Averaging the direction removes it.

If you need the school rule for a specific report, be explicit about it rather than fighting round:

python
from decimal import Decimal, ROUND_HALF_UP
Decimal("2.5").quantize(Decimal("1"), rounding=ROUND_HALF_UP)   # 3

Converting between them

python
int("42")      # 42, from text
int(3.9)       # 3 — truncates towards zero, it does not round
float("3.14")  # 3.14
int("3.9")     # ValueError: invalid literal for int() with base 10: '3.9'

That last one catches people. int() will convert a float to an int, and will convert a string of digits to an int, but it will not do both steps at once. int(float("3.9")) works.

A useful habit

When a calculation gives an answer you did not expect, print the types before you print the values:

python
print(type(total), type(count), total, count)

Half of all wrong arithmetic in a beginner's program is a string that looks like a number, and type() tells you in one line. The other half is integer division where you wanted /.

The float thing is not a Python quirk to be routed around. Every language using IEEE 754 doubles behaves identically, including JavaScript, Java, C and your spreadsheet. Excel hides it by displaying fewer digits; the error is still there.

The one thing to keep

`/` always returns a float and `//` rounds downwards, and 0.1 + 0.2 is not 0.3 because a float stores binary fractions with 53 bits of mantissa.

Before you move on

A stock program adds 0.1 to a total ten times and then tests `if total == 1.0:` to stop. It never stops. What is the mechanism, and what fixes it?

Pick the one you would defend. Nobody sees your answer.

No ads. No data sale. No public scores on people. Ever.

© 2026 Addaly

Numbers: whole, decimal, and the one that surprises everybody · Python, From Zero, For AI · Addaly