> und "denke" dir die zwei nullen einfach hinten dran..
Wieso 2 Nullen. Hex vielleicht, aber dezimal sind
da keine 2 Nullen.
Als erstes:
* Grundregel: Divisionen schiebt man in der Verarbeitungs-
kette soweit nach rechts wie möglich.
1 | uint_Output = ( (uint_Input-uint_Dmin)/(uint_Dmax-uint_Dmin) ) << 16 );
|
Wenn die Division schon 0 ergeben hat, kannst du nach links
schieben soviel du willst, das bleibt trotzdem 0.
Also Divisionen nach hinten:
Aus
uint_Output = (uint_Input-uint_Dmin)/(uint_Dmax-uint_Dmin)*65536
wird
uint_Output = (uint_Input-uint_Dmin)*65536/(uint_Dmax-uint_Dmin)
Wobei sich jetzt natürlich das Problem ergibt, dass die
Multiplikation in int, bzw. unsigned int gemacht wird und
somit einen Overflow produzieren kann. Um das zu vermeiden
stellen wir erst mal sicher, dass die Multiplikation
als long Multiplikation durchgeführt wird.
uint_Output = (uint_Input-uint_Dmin)*65536UL/(uint_Dmax-uint_Dmin)
Bei einer Berechnung werden immer beide beteiligte Operanden
auf gleiche Datentypen gebracht. Ist einer der beiden long, wird
auch der andere zu long und die Operation wird dann als long
Operation durchgeführt. 65536UL ist ein long (genauer:
ein unsigned long), ergo: die Multiplikation wird komplett
in unsigned long durchgeführt und das Ergebnis ist ebenfalls
ein unsigned long.
Somit sind Overflows soweit gebannt.
Ach ja. Das Schieben um 16 Bit anstatt der Multiplkation.
Diese Optimierung überlassen wir besser dem Compiler. Das
können die seit 30 Jahren zuverlässig.