Code:
// This is the original map() function in Arduino Core
long map1(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;
}
// This is the same but with the +1 "range extrension" as suggested by st42
long mapPlus1(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min + 1) / (in_max - in_min + 1) + out_min;
}
// This is another version of map with rounding done only with integer calculations
// as suggested by M.Kooijman
long mapRound(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)/2) / (in_max - in_min) + out_min;
}
void setup(void) {
Serial.begin(115200);
delay(2000);
long x;
Serial.printf("Range 0-20 to 0-4\n");
Serial.printf(" x map map1 map(+1) map(round)\n");
for (x=-10; x<=30; x++) {
Serial.printf("%6ld %6ld %6ld %6ld %6ld\n", x,
map(x, 0, 20, 0, 4),
map1(x, 0, 20, 0, 4),
mapPlus1(x, 0, 20, 0, 4),
mapRound(x, 0, 20, 0, 4));
}
Serial.printf("\n\n");
Serial.printf("Range 0-5 to 0-1023\n");
Serial.printf(" x map map1 map(+1) map(round)\n");
for (x=-5; x<=10; x++) {
Serial.printf("%6ld %6ld %6ld %6ld %6ld\n", x,
map(x, 0, 5, 0, 1023),
map1(x, 0, 5, 0, 1023),
mapPlus1(x, 0, 5, 0, 1023),
mapRound(x, 0, 5, 0, 1023));
}
}
void loop() {}
with the results: