gawroon7 is correct that there is an issue in the map() function and I have pointed out the problem is that is that map() is incorrectly calculating the number of points in each of the ranges when doing the percentage calculation to calculate the offset into the target range.
map() defines each range as a from,to pair and the range is inclusive of from and to.
See here: map() - Arduino Reference
So the number of points in a range pair is (from-to +1)
map() incorrectly calculates the number of points as (from - to)
Because of this, the miscalculation of the mapped value that map() returns is affected more as a range size gets smaller since the "off by one" miscalculation of the number of points in the range is a larger percentage of the actual number of points in the range.
i.e. smaller ranges will see a larger calculation error and large ranges will see a much smaller error in mapped values.
gawroon7 offered this correction to map()
y = (x - in_min) * (out_max - out_min +1) / (in_max - in_min) + out_min
However, both range sizes need to be incremented by one not just the output range as gawroon7 showed in the first post since both ranges are inclusive of the "to" point.
So it really needs to be:
y = (x - in_min) * (out_max - out_min +1) / (in_max - in_min+1) + out_min
--- bill
More discussion with respect to AOL's comments below.
AWOL:
Argue and assume all you like, but map (1020, 0, 255, 0, 1023) for example, does give the same value as 1020 / 4.(map (1020, 0, 256, 0, 1024) does)
I don't make assumptions. I based my comments on math and the math in map() is incorrect.
map(3,1,10,1,5) should be 2 not 1
Why are you bringing up an entirely different set of range mappings than what was being discussed?
The discussion was mapping a larger range to a smaller range.
And in the case of post #6, post #9 and my posts, specifically mapping a value from a range 0 to 1023 to a range of 0 to 255
Post #6 was saying:
val/4 != map(val, 0,1023, 0, 255)
to which in post #9 you said:
. . . you fail the interview.
The two are not equivalent.
And my comments and examples related to post #6 and post #9 but also shows what the OP (gawroon7) was seeing.
But the main point I was making was that if the map() calculation were correct, then val/4 would be equal to map(val,0,1023,0,255) for all values 0 to 1023.
The ranges in your recent post #19 is not what INTP (post#3), your response to #6 (post#9), and my response to your #6 (post #18) were talking about. Go back and read the posts closer (particularly #6 and my #18) and in particular, pay close attention to the documentation on map() on the page:
The map() documentation is very clear and very explicitly states that the ranges are
fromLow to fromHigh and toLow to toHigh (inclusive)
It does not state that the 2nd paramter is must be one higher than the actual highest value in the range.
In fact it states that if you send it fromHigh you will get toHigh.
So if you have a range of values that can be any value from 0 to 1023 (inclusive) you should be using 0,1023 not 0,1024 when using map()
So the proper range as shown in my examples and in the example in post #6 were using the
ranges: map(x, 0, 1023, 0, 255)
And that is why I showed examples and provided and example sketch that used the proper parameters.
I showed a simpler example that dropped the ranges down for demonstration to be able to show the full mapping table.
And it shows how the map function is incorrect by showing a simple example that shows that map(3,1,10,1,5) returns 1 instead of 2
But if you fix the portion of the calculation that calculates the ranges correctly to calculate it correctly, then the final mapped value will also be correct.
i.e. when the range size is correct
map(3,1,10,1,5) will properly return 2 instead of incorrectly return 1 as it does now.
--- bill
