diff --git a/analysis/#02 — Floating Point Equality Is a Lie/readmy.md b/analysis/#02 — Floating Point Equality Is a Lie/readmy.md new file mode 100644 index 0000000..0de5c67 --- /dev/null +++ b/analysis/#02 — Floating Point Equality Is a Lie/readmy.md @@ -0,0 +1,261 @@ +# Analysis #02 — Floating Point Equality Is a Lie + +## Problem + +At interviews, you often see something like: + +> Compare two floating point numbers and determine if they are equal. + +Typical answer: + +```cpp +if (a == b) { } +``` + +Or the “better” version: + +```cpp +fabs(a - b) < 1e-9 +``` + +Looks correct. In real engineering — not enough. + +--- + +## The Real Issue + +The problem is not that `==` is bad. + +The problem is the assumption: + +> There exists one correct way to compare floating point numbers. + +There isn’t. + +--- + +## Why `==` Fails + +Classic example: + +```cpp +double a = 0.1 + 0.2; +double b = 0.3; +``` + +`a != b` + +Reasons: +- binary representation +- rounding errors +- accumulation of operations + +--- + +## Why “Just Use Epsilon” Is Not Enough + +### Scale problem + +```cpp +a = 1e9; +b = a + 0.1; +``` + +`1e-9` is meaningless here. + +--- + +### Near-zero problem + +```cpp +a = 1e-12; +b = 2e-12; +``` + +`1e-9` is too large. + +--- + +### Meaning problem + +What are these values? + +- sensor readings? +- computed values? +- scaled integers? +- geometry? + +Without context, comparison is undefined. + +--- + +## What This Actually Tests + +In interviews, this checks: + +- awareness of IEEE754 +- prior exposure to the trap +- memorized epsilon usage + +Not real engineering thinking. + +--- + +## Real-World Behavior + +### Sensor example + +```cpp +if (temperature == target) +``` + +System never stabilizes. + +Reality: +- noise +- quantization +- jitter + +Solution: +- tolerance +- hysteresis +- filtering + +--- + +### Computation paths + +```cpp +double x = (a + b) + c; +double y = a + (b + c); +``` + +Different results. + +--- + +### Scaled data (CAN-like) + +```cpp +raw = 1234; +value = raw * 0.1; +expected = 123.4; +``` + +Comparison fails. + +--- + +## Demo Code + +A full demonstration program is available: + +- examples/main.cpp + +It shows: +- where `==` fails +- where fixed epsilon fails +- why scale matters +- how noise breaks naive logic +- why hysteresis is often required + +--- + +## Example Output (fill with your own results) + +Below you can include actual output from your system. + +```text +[insert your real output here] +``` + +Use this section to demonstrate: +- how behavior changes with different eps values +- how noise affects stability +- differences between float and double +- how hysteresis stabilizes the system + +--- + +## Better Approaches + +### Absolute + +```cpp +fabs(a - b) < abs_eps +``` + +--- + +### Relative + +```cpp +fabs(a - b) < rel_eps * max(fabs(a), fabs(b)) +``` + +--- + +### Combined + +```cpp +fabs(a - b) <= max(abs_eps, rel_eps * max(fabs(a), fabs(b))) +``` + +--- + +### Or Avoid Float + +Compare: +- raw values +- fixed-point +- integers + +--- + +### Or Change the Question + +Instead of: + +> Are values equal? + +Ask: + +> Are they close enough for the system? + +--- + +## Common Mistakes + +- Using `==` +- Fixed epsilon everywhere +- Only relative error +- Only absolute error +- Blind rounding + +--- + +## Key Takeaway + +Floating point comparison is not a trick. + +It is a modeling problem. + +--- + +## Project Perspective + +Does this problem exist in real engineering? + +Yes. + +In interview form? + +Almost never. + +Because real systems have: +- noise +- scale +- constraints +- consequences + +And no universal epsilon.