Map function returns a negative number for large ranges
- Dominant language
- Java
- Stars
- 14.6k
- Forks
- 7k
- PR merge metrics
- No merged PRs in 30d
Description
For example: map (20000, 0, 40000, 0, 120000) returns -47,374 and should return 60,000. This is clearly a number over run. The issue is the order of operations that is used to calculate the value. Per the documentation, map is defined as:
```c++
long map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
```
Everything is defined as long, so that's not the problem. If you look at the math for the example above, the map function will execute as follows:
1) x - in_min = 4,000
2) out_max - out_min = 120,000
3) the (x - in_min) * (out_max - out_min) = 2,400,000,000.
Step 3 generates a number that's too big to be stored in a long. This is the overrun.
If map is changed to execute the division first, large numbers during the calculation are avoided. So I suggest map to be changed to add parentheses around the division to execute that first. So map would be:
```c++
long map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * ((out_max - out_min) / (in_max - in_min)) + out_min;
}
```
For the given example, this would execute as:
1) out_max - out_min = 4,000
2) in_max - in_min = 1,200,000
3) out_max - out_min) / (in_max - in_min = 3
4) (x - in_min) * ((out_max - out_min) / (in_max - in_min)) = 60,000
Everything fitting within the long variable.
Contributor guide
Research direction
Start by locating the documented C++ map(long...) implementation; the issue names no source file or test. Reproduce the supplied large-range example, then verify that the result is 60,000 without breaking the documented map behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100