Numbers¶
One line: C lets you compare any two numbers and does not stop an impossible floating-point operation, and in both cases the answer comes from rules you did not see applied: the conversion that makes -1 equal to UINT_MAX before -1 < 1u is compared, and the IEEE 754 default that turns sqrt(-42.0) into NaN and records the problem in a flag instead of stopping the program.
This chapter started from Rust in Action (Tim McNamara, Manning 2021), §2.3.3, "Comparing numbers", read alongside the Rust and Python libraries. Rust refuses comparisons that C compiles, and C does not have Python's exceptions, so each lesson runs the C version of a claim from that section and shows where C's answer comes from.
| Lesson | Level | What it settles |
|---|---|---|
| Comparing signed and unsigned | 201 | Why C compiles the i32 < u16 comparison that Rust refuses, why 10 < (unsigned short)100 is fine and -1 < 1u is false, which flag warns about it, and the two ways to compare correctly |
| A float exception is a flag | 201 → 301 | What an IEEE 754 exception really is: the five sticky flags <fenv.h> reads, why constants hide them, errno against flags on glibc and macOS, the trap you have to ask for, and why 0.1 + 0.2 == 0.3 is false in double and true in float |
Where this connects¶
- The Rust library's Numbers chapter ↗ has the Rust side of the same book section: comparing two number types ↗, the section's claims checked one by one ↗, and what a float stores ↗.
- The Python library's Numbers chapter ↗ has an
intwith no width and afloatthat raises where C returns NaN. - The Math library's Machine numbers ↗ explains why a float is an exact member of a finite set, and every operation exact arithmetic followed by rounding.
Planned¶
Rough order, not a promise:
- Widths and
<stdint.h>— whatintandlongare on each machine, and the exact-width types that stop you asking - Signed overflow — undefined, unlike the unsigned wrap-around in this chapter, and what the optimizer assumes because of it