Skip to content

Map function returns a negative number for large ranges #10557

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
rjp119 opened this issue Jul 25, 2020 · 1 comment
Open

Map function returns a negative number for large ranges #10557

rjp119 opened this issue Jul 25, 2020 · 1 comment
Labels
Component: Core Related to the code for the standard Arduino API Type: Bug

Comments

@rjp119
Copy link

rjp119 commented Jul 25, 2020

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:

  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:

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.

@rjp119 rjp119 closed this as completed Jul 25, 2020
@rjp119 rjp119 reopened this Jul 25, 2020
@rjp119 rjp119 changed the title Map function returns -negative number for large ranges Map function returns a negative number for large ranges Jul 25, 2020
@per1234 per1234 added the Component: Core Related to the code for the standard Arduino API label Aug 1, 2020
@dsyleixa
Copy link

another (IMO better) option would be to perform all calculations in (double)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Core Related to the code for the standard Arduino API Type: Bug
Projects
None yet
Development

No branches or pull requests

3 participants