float#
float is a 64-bit IEEE 754 double. Same rounding pitfalls as
every other language with IEEE doubles. The operator’s instinct
should be to reach for decimal.Decimal whenever money,
totals, or exact comparisons matter.
0.1 + 0.2 # 0.30000000000000004
1.0 == 0.1 + 0.2 + 0.7 # False
from decimal import Decimal
Decimal("0.1") + Decimal("0.2") # Decimal("0.3")
Special values are first-class.
import math
math.inf, -math.inf, math.nan
math.isnan(x); math.isfinite(x)
Division by zero on floats produces ZeroDivisionError, not
inf. To get IEEE behaviour use numpy or compute
explicitly.
Methods#
Method |
Effect |
|---|---|
|
|
|
Pair of ints |
|
Hexadecimal string representation ( |
|
Parse a hexadecimal string back to |
|
Complex conjugate (returns the same |
is_integer is the operator’s check for “did this divide
cleanly”.
(3.0).is_integer(), (3.14).is_integer()
(True, False)
as_integer_ratio recovers the exact rational the float
represents.
(0.5).as_integer_ratio()
(1, 2)
hex and float.fromhex round-trip a float without going
through decimal text.
(1.5).hex()
'0x1.8000000000000p+0'
float.fromhex('0x1.8000000000000p+0')
1.5
Operator overloading#
float implements the standard numeric dunder methods.
Operator |
Dunder |
Returns |
|---|---|---|
|
|
Sum. |
|
|
Difference. |
|
|
Product. |
|
|
True division. |
|
|
Floor division. |
|
|
Modulo (IEEE remainder). |
|
|
Exponentiation. |
|
|
Negation. |
|
|
Absolute value. |
|
|
Banker’s rounding. |
|
|
Equality (with IEEE NaN caveats). |
|
|
Less than. |
|
|
Hash (consistent with |
|
|
Truncating integer conversion. |
|
|
Float conversion. |
|
|
|
__r*__ reflected forms and __i*__ in-place forms exist
for every binary operator above.
A vector class with __add__ and __mul__ lets the
operator do float arithmetic on a pair.
class Vec2:
def __init__(self, x, y): self.x, self.y = x, y
def __add__(self, other): return Vec2(self.x + other.x, self.y + other.y)
def __mul__(self, k): return Vec2(self.x * k, self.y * k)
def __repr__(self): return f"Vec2({self.x}, {self.y})"
Vec2(1.0, 2.0) + Vec2(3.5, 4.0)
Vec2(4.5, 6.0)
Reflected __rmul__ makes 2.0 * v work even when the
float is on the left (it returns NotImplemented first;
Python then asks v).
class Vec2:
def __init__(self, x, y): self.x, self.y = x, y
def __mul__(self, k): return Vec2(self.x * k, self.y * k)
def __rmul__(self, k): return self.__mul__(k)
def __repr__(self): return f"Vec2({self.x}, {self.y})"
3.0 * Vec2(1.0, 2.0)
Vec2(3.0, 6.0)
References#
int for arbitrary-precision integers.
complex for complex numbers.
Operators for arithmetic operators.
decimal — Decimal fixed-point and floating-point arithmetic.
What Every Computer Scientist Should Know About Floating-Point Arithmetic.