#02 — Floating Point Equality Is a Lie
This commit is contained in:
261
analysis/#02 — Floating Point Equality Is a Lie/readmy.md
Normal file
261
analysis/#02 — Floating Point Equality Is a Lie/readmy.md
Normal file
@@ -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.
|
||||||
Reference in New Issue
Block a user