Numbers: int, float, Decimal & Fraction
Reviewed & published by Brayan K
Python offers four numeric types for different jobs: int for exact whole numbers of any size, float for fast approximate decimals, Decimal for exact base-10 math like money, and Fraction for exact rational numbers with no rounding at all.
Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Choosing the right number type prevents a whole category of subtle bugs — especially the infamous "0.1 + 0.2" surprise that bites every programmer eventually.
What You'll Learn in This Lesson
- Python ints have unlimited precision
- Why 0.1 + 0.2 isn't exactly 0.3
- Using Decimal for exact money math
- Exact ratios with Fraction
- Rounding and formatting numbers
- Where complex numbers fit in
1 int: Unlimited Precision & float Pitfalls
Python ints never overflow — they grow as large as needed. Floats, however, are binary approximations, so some decimals can't be stored exactly. That's why 0.1 + 0.2 isn't quite 0.3:
# int has arbitrary precision — no overflow ever
big = 2 ** 100
print(big) # 1267650600228229401496703205376
print(len(str(big))) # 31 digits, computed exactly
# float is fast but approximate
print(0.1 + 0.2) # 0.30000000000000004
print(0.1 + 0.2 == 0.3) # False (!!)
# The safe way to compare floats: math.isclose
import math
print(math.isclose(0.1 + 0.2, 0.3)) # True# Watch float error accumulate, then fix the comparison
total = 0.0
for _ in range(10):
total += 0.1
print("total =", total)
print("== 1.0?", total == 1.0)
import math
print("isclose?", math.isclose(total, 1.0))
# ✅ Expected output:
# total = 0.9999999999999999
# == 1.0? False
# isclose? True2 Decimal for Exact Money Math
decimal.Decimal stores numbers in base 10, exactly as written, so currency arithmetic is precise. The golden rule: build Decimals from strings, never from floats (which would import the float's error):
from decimal import Decimal
# From strings: exact
print(Decimal("0.1") + Decimal("0.2")) # 0.3 (exactly!)
# A real price calculation
price = Decimal("19.99")
qty = 3
subtotal = price * qty
print(subtotal) # 59.97
# quantize() rounds to a fixed number of places (e.g. cents)
tax = subtotal * Decimal("0.08")
print(tax) # 4.7976
print(tax.quantize(Decimal("0.01"))) # 4.80
# WRONG: Decimal from a float drags in the float error
print(Decimal(0.1)) # 0.1000000000000000055511151231257827021181583404541015625Use quantize() to round to cents, and you have correct, auditable money math — exactly what banking and e-commerce code requires.
3 Fraction, round() & complex
fractions.Fraction keeps exact ratios with no rounding ever. round() and f-string formatting control how numbers display. And complex handles imaginary numbers when you need them:
from fractions import Fraction
# Exact rational arithmetic — thirds and sixths, no rounding
print(Fraction(1, 3) + Fraction(1, 6)) # 1/2
print(Fraction(2, 4)) # 1/2 (auto-reduced)
# round() and formatting
print(round(3.14159, 2)) # 3.14
print(f"{1234.5678:,.2f}") # 1,234.57 (commas + 2 dp)
print(f"{0.25:.1%}") # 25.0% (as a percent)
# complex numbers: j is the imaginary unit
z = 2 + 3j
print(z.real, z.imag) # 2.0 3.0
print(abs(z)) # 3.605551275463989from fractions import Fraction
# Add a series of fractions exactly, then see the float version
parts = [Fraction(1, 2), Fraction(1, 3), Fraction(1, 6)]
total = sum(parts, Fraction(0))
print("Exact:", total)
print("As float:", float(total))
# ✅ Expected output:
# Exact: 1
# As float: 1.0🎯 Your Turn: Fill in the Blanks
Replace each ___ so the cart total is exact to the cent. Remember: build Decimals from strings.
# 🎯 YOUR TURN: compute an exact cart total
from decimal import Decimal
prices = ["4.99", "1.49", "9.95"]
total = Decimal("0")
for p in prices:
total += Decimal(___) # build a Decimal from the price string
# Round the final total to cents
total = total.quantize(Decimal("0.01"))
print("Total:", total)
# Expected output:
# Total: 16.43Common Errors
if 0.1 + 0.2 == 0.3: # False! never runs
print("equal")import math
if math.isclose(0.1 + 0.2, 0.3):
print("equal")❌ Building a Decimal from a float
Decimal(0.1) # 0.1000000000000000055511151231257827...✅ Build from a string
Decimal("0.1") # exactly 0.1❌ Using float for currency
print(1.10 * 3) # 3.3000000000000003 — off by a hair✅ Use Decimal for money
print(Decimal("1.10") * 3) # 3.30🎯 Mini Challenge: Split the Bill
Split a restaurant bill three ways using Decimal so the cents always add up correctly — and give the leftover penny to the first person.
# 🎯 Mini Challenge: split a bill 3 ways, exactly
from decimal import Decimal, ROUND_DOWN
total = Decimal("100.00")
people = 3
# Floor each share to cents, then hand leftover pennies to person 1
share = (total / people).quantize(Decimal("0.01"), rounding=ROUND_DOWN)
shares = [share, share, share]
remainder = total - share * people
shares[0] += remainder
print("Shares:", shares)
print("Sum:", sum(shares))
# Expected output:
# Shares: [Decimal('33.34'), Decimal('33.33'), Decimal('33.33')]
# Sum: 100.00📚 Keep Learning
- Python docs: Floating Point Arithmetic — Issues and Limitations
- Python docs: decimal — Decimal fixed-point arithmetic
- Python docs: fractions — Rational numbers
Frequently Asked Questions
Lesson complete — you pick the right number type every time!
You understand that int is unlimited, why 0.1 + 0.2 drifts, how Decimal keeps money exact, how Fraction gives perfect ratios, and how to round and format numbers cleanly — never comparing floats with == again.
Practice quiz
What does 0.1 + 0.2 == 0.3 evaluate to in Python?
- True
- An error
- False
- None
Answer: False. Float rounding makes 0.1 + 0.2 equal 0.30000000000000004, so the comparison is False.
What is the safe way to compare two floats for near-equality?
- math.isclose(a, b)
- ==
- round(a) == round(b)
- a is b
Answer: math.isclose(a, b). math.isclose(a, b) checks whether floats are effectively equal despite rounding.
How large can a Python int get?
- 32 bits
- 64 bits
- Up to 2**53
- As big as memory allows (arbitrary precision)
Answer: As big as memory allows (arbitrary precision). Python ints have arbitrary precision and grow as needed, so 2**100 is exact.
Which type should you use for exact money math?
- float
- decimal.Decimal
- complex
- int only
Answer: decimal.Decimal. Decimal stores numbers in base 10 exactly, avoiding float rounding errors with currency.
What does Decimal('0.1') + Decimal('0.2') equal?
- 0.3
- 0.30000000000000004
- 0.30
- an error
Answer: 0.3. Decimals built from strings are exact, so the sum is exactly 0.3.
Why should you avoid Decimal(0.1) (from a float)?
- It is faster but wrong
- It raises an error
- It imports the float's rounding error
- It rounds to 0
Answer: It imports the float's rounding error. Building a Decimal from a float drags in the float's tiny error; build from a string instead.
What does Fraction(1, 3) + Fraction(1, 6) equal?
- Fraction(2, 9)
- Fraction(1, 2)
- 0.5
- Fraction(1, 9)
Answer: Fraction(1, 2). 1/3 + 1/6 = 1/2 exactly, with no rounding.
What does round(3.14159, 2) return?
- 3.1
- 3.142
- 3
- 3.14
Answer: 3.14. round() to 2 decimal places gives 3.14.
For z = 2 + 3j, what are z.real and z.imag?
- 3.0 and 2.0
- 2.0 and 3.0
- 2 and 3j
- 5.0 and 0.0
Answer: 2.0 and 3.0. j is the imaginary unit, so z.real is 2.0 and z.imag is 3.0.
Which method rounds a Decimal to a fixed number of places like cents?
- round_to()
- fix(2)
- quantize(Decimal('0.01'))
- to_cents()
Answer: quantize(Decimal('0.01')). quantize(Decimal('0.01')) rounds a Decimal to two places for money.
Continue this course
- Previous: Binary Search with bisect
- Next: Strings, Bytes & Unicode Encodings — str vs bytes, encode/decode, UTF-8, and fixing UnicodeDecodeError
- Quick reference: Python cheat sheet
Frequently asked questions
Why does 0.1 + 0.2 not equal 0.3 in Python?
Because float uses binary (base-2) floating point, and 0.1, 0.2, and 0.3 cannot be represented exactly in binary — just as 1/3 cannot be written exactly in decimal. The tiny rounding errors add up, so 0.1 + 0.2 comes out as 0.30000000000000004. This is not a Python bug; every language using IEEE 754 floats behaves the same way.
Should I use float for money?
No. Float rounding errors can make totals off by a cent, which is unacceptable for currency. Use decimal.Decimal, which stores numbers in base 10 exactly as you write them, so 0.1 + 0.2 really is 0.3. Create Decimals from strings — Decimal('0.1') — never from floats, or you import the float's error.
How big can a Python int get?
As big as your memory allows. Unlike many languages with fixed 32- or 64-bit integers, Python ints have arbitrary precision and grow automatically, so 2 ** 1000 computes exactly with no overflow. This makes Python excellent for cryptography, combinatorics, and any math involving enormous whole numbers.
When would I use Fraction?
Use fractions.Fraction when you need exact rational arithmetic — thirds, sevenths, repeating decimals — with no rounding at all. Fraction(1, 3) + Fraction(1, 6) gives exactly Fraction(1, 2). It's ideal for math-heavy code, exact ratios, or teaching, where even Decimal's fixed precision isn't perfectly exact.