J-M-L a donné une solution pour que cela fonctionne. Mais cela n'explique pas pourquoi le code de départ ne fonctionne pas.
La fonction map est définie par:
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;
}
et que l'on l'appelle par
uint32_t val=map(65535,0,65535,62500 ,375);
ou par
uint32_t val=map(65535ul,0ul,65535ul,62500ul ,375ul);
ne changera rien au problème car les nombres sont de toutes façon transformés en long. La conversion peut éventuellement prendre un peu plus de temps.
Quand on fait le calcul avec ces données, on va dépasser la capacité des entiers longs dans la multiplication du numérateur (x - in_min) * (out_max - out_min) . Ce n'est pas très grave sauf que l'opération globale est environ (j'ai laissé tomber le signe - pour l'instant):
65535 * 62125 / 65535
et si JE fais cette opération, je vais trouver 62125. Mais la simplification par 65535 ne peut être faite par le compilateur. il va donc faire la multiplication, et comme cela dépasse la vraie opération sera:
[65535 * 62125 -0x1.000.000]/ 65535 soit encore
[65535 * 62125] / 65535 - 0x1.000.000/ 65535
La première partie va bien donner 62125, mais 0x1.000.000 n'est pas divisible par 65535 et va donner un arrondi que l'on va retrouver dans les deux résultats finaux.
Si on passe des int16_t, comme on a enlevé 0x1.000.000/ 65535 en plus, le résultat va de nouveau déborder quand o le mettra dans le int ce qui va compenser le premier débordement. On se retrouve avec la première valeur mais avec l'erreur d'arrondi soit 376 au lieu de 375.
Si on passe par les uint32_t, on ne va pas avoir le deuxième débordement, et on a donc la même valeur au débordement des int près, c'est à dire modulo 65536
65536+376 donne bien le deuxième résultat.
La fonction map est faite pour convertir un résultat de la conversion analogique 0/1024 dans une autre échelle, et cela ne devrait pas déborder. Le débordement n'est pas prévu. Il manque une petite phrase:
le produit de la plage d'entrée par la plage de sortie doit tenir dans un long (max 0x7000.000)