271 lines
3.8 KiB
Markdown
271 lines
3.8 KiB
Markdown
# Analysis #01 — When Arithmetic Cannot Be Trusted
|
|
|
|
## 1. The Problem
|
|
|
|
Look at this code:
|
|
|
|
```cpp
|
|
int a;
|
|
int b;
|
|
int c;
|
|
|
|
// ...
|
|
|
|
if (a + b > c)
|
|
```
|
|
|
|
It looks simple.
|
|
|
|
You have probably written this many times.
|
|
|
|
Most people will say:
|
|
“Nothing is wrong.”
|
|
|
|
But something is wrong.
|
|
|
|
---
|
|
|
|
## 2. The Hidden Assumption
|
|
|
|
This code assumes:
|
|
|
|
> `a + b` always works correctly.
|
|
|
|
In real systems, this is not always true.
|
|
|
|
---
|
|
|
|
## 3. What Can Go Wrong
|
|
|
|
In C/C++:
|
|
|
|
- `int` has limits
|
|
- `a + b` can overflow
|
|
- signed overflow is undefined
|
|
|
|
This means:
|
|
|
|
> The result of `a + b` can be wrong.
|
|
> And the `if` will use that wrong value.
|
|
|
|
At this point, many people think:
|
|
“I just need a bigger type.”
|
|
|
|
But that is not the real problem.
|
|
|
|
---
|
|
|
|
## 4. Why Simple Fixes Do Not Help
|
|
|
|
Common ideas:
|
|
|
|
- “Use `long`”
|
|
- “Rewrite as `a > c - b`”
|
|
|
|
These do not solve the problem.
|
|
|
|
> They only move the problem somewhere else.
|
|
|
|
---
|
|
|
|
## 5. The Real Problem
|
|
|
|
This is not about math.
|
|
|
|
This is about **data you cannot trust**.
|
|
|
|
- input values can be wrong
|
|
- result can be invalid
|
|
- invalid result must not be used
|
|
|
|
In interviews, data is always clean.
|
|
|
|
In real systems, it is not.
|
|
|
|
Sensors fail.
|
|
Signals disappear.
|
|
Values go outside limits.
|
|
|
|
And then simple code becomes dangerous.
|
|
|
|
---
|
|
|
|
## 🧪 A Real-World Example
|
|
|
|
During testing of a prototype vehicle, the system did not start.
|
|
|
|
The team checked signals and wiring.
|
|
There was no response from the transmission.
|
|
|
|
They thought:
|
|
something is wrong with the signal.
|
|
|
|
Later they found the real reason:
|
|
|
|
> There was no transmission.
|
|
> It was still on the shelf.
|
|
|
|
It sounds obvious now.
|
|
|
|
But at that moment, everyone believed the system was complete.
|
|
|
|
---
|
|
|
|
## 💡 Lesson
|
|
|
|
Before you debug logic or data, check your assumptions.
|
|
|
|
> Maybe the system is not what you think it is.
|
|
|
|
---
|
|
|
|
## ⚠️ Do Not Fix It With Math
|
|
|
|
> Math does not fix broken data.
|
|
> It only hides the problem.
|
|
|
|
When something looks wrong:
|
|
|
|
- do not rewrite the formula
|
|
- do not try to “make it work”
|
|
- do not hide the issue
|
|
|
|
> Do not fix logic with math.
|
|
> Report the problem.
|
|
|
|
---
|
|
|
|
## 6. Why This Code Is Rare in Real Systems
|
|
|
|
In real-time and embedded systems:
|
|
|
|
- calculations are done before conditions
|
|
- conditions use prepared values
|
|
- time is limited
|
|
- input ranges are defined
|
|
|
|
So this:
|
|
|
|
```cpp
|
|
if (a + b > c)
|
|
```
|
|
|
|
is already suspicious.
|
|
|
|
---
|
|
|
|
## 7. What Real Systems Do
|
|
|
|
Real systems ask:
|
|
|
|
> “Can I trust this result?”
|
|
|
|
If not, they do not use it.
|
|
|
|
---
|
|
|
|
### Typical behavior
|
|
|
|
If `a + b`:
|
|
|
|
- overflows
|
|
- or gives a value outside limits
|
|
|
|
then:
|
|
|
|
1. Drop it
|
|
Do not use the result.
|
|
|
|
2. Mark it as invalid
|
|
- invalid
|
|
- not plausible
|
|
- bad frame (for example CAN)
|
|
|
|
3. Report it
|
|
- error counter
|
|
- diagnostics
|
|
|
|
4. Continue working
|
|
Wait for valid data.
|
|
|
|
---
|
|
|
|
## 8. Example
|
|
|
|
```cpp
|
|
auto result = safe_add(a, b);
|
|
|
|
if (result.invalid)
|
|
{
|
|
publish_invalid();
|
|
error_counter++;
|
|
return;
|
|
}
|
|
|
|
if (result.value > c)
|
|
{
|
|
update_state();
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Key Idea
|
|
|
|
> Do not trust bad data.
|
|
> Do not use bad results.
|
|
|
|
---
|
|
|
|
## 10. Final Answer
|
|
|
|
What is wrong with:
|
|
|
|
```cpp
|
|
if (a + b > c)
|
|
```
|
|
|
|
Answer:
|
|
|
|
> It assumes the calculation is always correct.
|
|
> In real systems, it is not.
|
|
|
|
---
|
|
|
|
## 11. Find Problems Before Runtime
|
|
|
|
Handling errors at runtime is not enough.
|
|
|
|
We must also find problems before release.
|
|
|
|
---
|
|
|
|
### In testing we:
|
|
|
|
- test near limits (INT_MAX, INT_MIN)
|
|
- send invalid data
|
|
- use fuzz testing
|
|
- replay real logs (for example CAN)
|
|
|
|
---
|
|
|
|
### We want to know:
|
|
|
|
- Where can overflow happen?
|
|
- What inputs cause it?
|
|
- Does the system drop invalid data?
|
|
- Does bad data go further?
|
|
|
|
---
|
|
|
|
## 12. Final Thought
|
|
|
|
> The system must survive bad data.
|
|
> The tools must find it.
|
|
|
|
Computers do not work with perfect numbers.
|
|
|
|
Real engineering is not about perfect formulas.
|
|
|
|
It is about systems that work even when data is not perfect.
|