03_Numbers — what == means between two numbers¶
Level: 201 · for Python programmers, especially ones coming from Rust or C
Python's numbers look like the least surprising part of the language. An int never overflows, 1 == 1.0 just works, and nothing needs a cast. Each of those conveniences hides a decision the language made for you, and each one becomes visible the moment you compare two numbers that are not quite what you thought: an integer too big for a double, a decimal fraction binary cannot hold, or a NaN.
This chapter started from Rust in Action's section on comparing numbers, which asks the same questions of a language that refuses to compare two number types at all. The Rust and C libraries answer them for their own languages, and every page here links the matching page there.
| # | Lesson | The question it answers | Status |
|---|---|---|---|
| 1 | Comparing an int with a float |
Why is 2**53 + 1 == float(2**53 + 1) False in Python, when the cast Rust and C use says they are equal? |
written |
| 2 | Float equality and NaN | Why is 0.1 + 0.2 == 0.3 False, why does an epsilon test fail at 2000, and why is [nan] == [nan] True? |
written |
The second page ends with a ## Practice kata, indexed in KATAS.md.
What comes next here¶
Named rather than stubbed, because a folder name is a permanent URL and an empty one is clutter:
round()is not school rounding:round(2.5)is2, andround(2.675, 2)is2.67for a reason that is not the rounding mode//and%floor, and C truncates: why-7 // 2is-4in Python and-7 / 2is-3in C and Rust. The Rust side is written: three ways to divide a negative number ↗Decimalhas a context: precision, rounding and traps as process-wide state, and what that means for money. The Rust side, whererust_decimalhas no context, is written: Decimals ↗Fraction,complexand anintwith no ceiling: the types Python ships and Rust needs a crate for, already run side by side in the Rust library's Other number types ↗
Where this sits relative to the other libraries¶
The math library ↗ owns the numbers themselves: which values a double can hold, and why the gaps between them grow. The Rust library's 19_Numbers ↗ owns the fixed-width types and the casts between them. This chapter owns what Python does with the same doubles, which is often the opposite of what Rust does: it compares exactly where Rust converts, and it raises where Rust returns a NaN.