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:
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:
- x - in_min = 4,000
- out_max - out_min = 120,000
- 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:
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:
- out_max - out_min = 4,000
- in_max - in_min = 1,200,000
- out_max - out_min) / (in_max - in_min = 3
- (x - in_min) * ((out_max - out_min) / (in_max - in_min)) = 60,000
Everything fitting within the long variable.