 # map() function is skipping some results

I have the following code:

``````float min = 0.4;
float max = 3.6;

for (float x = min; x <= max; x += 0.1) {
int y = map(x, min, max, 1, 8);
Serial.print(x);
Serial.print(" ---> ");
Serial.println(y);
}
``````

And I get the following output:

``````0.40 ---> 1
0.50 ---> 1
0.60 ---> 1
0.70 ---> 1
0.80 ---> 1
0.90 ---> 1
1.00 ---> 3
1.10 ---> 3
1.20 ---> 3
1.30 ---> 3
1.40 ---> 3
1.50 ---> 3
1.60 ---> 3
1.70 ---> 3
1.80 ---> 3
1.90 ---> 3
2.00 ---> 5
2.10 ---> 5
2.20 ---> 5
2.30 ---> 5
2.40 ---> 5
2.50 ---> 5
2.60 ---> 5
2.70 ---> 5
2.80 ---> 5
2.90 ---> 5
3.00 ---> 5
3.10 ---> 8
3.20 ---> 8
3.30 ---> 8
3.40 ---> 8
3.50 ---> 8
3.60 ---> 8
``````

As you can probably guess, I’m trying to map a voltage in the range 0.4v-3.6v to an int in the range 1-8. The problem is that the numbers 2, 4, 6, and 7 are missing from the output.
Why is map() skipping these?
If this is the expected output from map(), is there an alternative that will give me the expected result?

The map() function uses integer math so will not generate fractions, when the math might indicate that it should do so. Fractional remainders are truncated, and are not rounded or averaged.

Right from the reference for map().

I'm not looking for fractions at all; the missing numbers are all integers. Can you offer an alternative solution to the problem?

``````for (int x = (min*10); x <= (int)(max*10); x += 1) { // Floats are messy, make it an int and shift the decimal place
int y = map(x, min *10, max *10, 1, 8);
Serial.print((float) (x * .1),1);
Serial.print(" ---> ");
Serial.println(y);
}
``````

Thanks @zhomeslice, I see how that works now. Unfortunately that solution leaves me with only one “8” instead of four which is what I’m looking for. Meaning, results are not evenly distributed.

I ended up borrowing the ofMap() function from the openFrameworks project.
ofMap() also contains the Arduino’s constrain() functionality built in and gives me a perfectly even distribution.

``````// NOTE: As opposed to Arduino's map(), here outputMax is exclusive
float ofMap(float value, float inputMin, float inputMax, float outputMin, float outputMax, bool clamp) {

if (fabs(inputMin - inputMax) < (float)1.19209290e-07){
return outputMin;
} else {
float outVal = ((value - inputMin) / (inputMax - inputMin) * (outputMax - outputMin) + outputMin);

if( clamp ){
if(outputMax < outputMin){
if( outVal < outputMax )outVal = outputMax;
else if( outVal > outputMin )outVal = outputMin;
}else{
if( outVal > outputMax )outVal = outputMax;
else if( outVal < outputMin )outVal = outputMin;
}
}
return outVal;
}
}
``````

Output using ofMap() is:

``````0.40 ---> 1
0.50 ---> 1
0.60 ---> 1
0.70 ---> 1
0.80 ---> 2
0.90 ---> 2
1.00 ---> 2
1.10 ---> 2
1.20 ---> 3
1.30 ---> 3
1.40 ---> 3
1.50 ---> 4
1.60 ---> 4
1.70 ---> 4
1.80 ---> 4
1.90 ---> 5
2.00 ---> 5
2.10 ---> 5
2.20 ---> 5
2.30 ---> 6
2.40 ---> 6
2.50 ---> 6
2.60 ---> 7
2.70 ---> 7
2.80 ---> 7
2.90 ---> 7
3.00 ---> 8
3.10 ---> 8
3.20 ---> 8
3.30 ---> 8
``````