Numbers (int, float, complex)
Python has three built-in numeric types: int for integers, float for real numbers with a decimal point, and complex for numbers with a real and imaginary part. Each has its own quirks worth understanding before you rely on them for anything precision-sensitive.
Integers: Arbitrary Precision
Python integers have no fixed size and no overflow. An int can grow as large as your machine’s memory allows — Python automatically switches to a bigger internal representation as numbers grow, so you never see wraparound bugs like you might in C or Java.
big = 2 ** 200 print(big) # 1606938044258990275541962092341162602522202993782792835301376 print(type(big)) # <class 'int'> -- still just a normal int, no overflow
Floats: IEEE 754 Double Precision
Python’s float is a 64-bit IEEE 754 double-precision number, the same representation used by most languages. This means floats have finite precision, and some decimal fractions cannot be represented exactly in binary — leading to the famous rounding surprise below.
print(0.1 + 0.2) # 0.30000000000000004 print(0.1 + 0.2 == 0.3) # False! # Safer comparison for floats: check "close enough" import math print(math.isclose(0.1 + 0.2, 0.3)) # True
Complex Numbers
Python has built-in support for complex numbers, written with a trailing j for the imaginary part. This is uncommon in everyday scripting but shows up in scientific computing, signal processing, and electrical engineering code.
z = 3 + 4j print(z) # (3+4j) print(z.real) # 3.0 print(z.imag) # 4.0 print(abs(z)) # 5.0 -- magnitude: sqrt(3**2 + 4**2) z2 = complex(1, 2) # also constructible via complex(real, imag) print(z + z2) # (4+6j)
Numeric Literals
Python offers several conveniences for writing numeric literals: underscores as visual separators in long numbers, and prefixes for hexadecimal, octal, and binary integers.
# Underscores for readability - purely visual, ignored by the parser population = 1_000_000 print(population) # 1000000 # Base literals hex_value = 0x1A # hexadecimal (base 16) oct_value = 0o17 # octal (base 8) bin_value = 0b101 # binary (base 2) print(hex_value, oct_value, bin_value) # 26 15 5 # Converting a number back to a base-prefixed string print(hex(26)) # 0x1a print(oct(15)) # 0o17 print(bin(5)) # 0b101
Converting Between Numeric Types
You can explicitly convert between numeric types with int(), float(), and complex(). Converting float to int truncates the decimal part rather than rounding.
print(int(3.9)) # 3 -- truncates, does NOT round print(int(-3.9)) # -3 -- truncates toward zero print(float(7)) # 7.0 print(complex(5)) # (5+0j) print(round(3.9)) # 4 -- use round() if you actually want rounding
Numeric Types at a Glance
Type | Example | Precision | Typical Use |
|---|---|---|---|
int | 42, 2**200 | Arbitrary (exact) | Counting, indexing, whole quantities |
float | 3.14, 1e10 | ~15-17 significant digits, IEEE 754 | Measurements, scientific calculations |
complex | 3 + 4j | Same as float for each component | Signal processing, engineering, math |
When Precision Really Matters
For money or any calculation where binary floating-point rounding errors are unacceptable, Python’s standard library offers two purpose-built modules:
decimal.Decimal— base-10 arithmetic with configurable precision, ideal for currency.fractions.Fraction— exact rational arithmetic (e.g. 1/3 stays exactly 1/3, never rounded).
from decimal import Decimal
from fractions import Fraction
print(Decimal("0.1") + Decimal("0.2")) # 0.3 -- exact!
print(Fraction(1, 3) + Fraction(1, 6)) # 1/2 -- exact rational result