A:
1  | erg = (int16_t)  (  (int32_t) a  *  (int32_t) b  );
  | 
Jo, sehe ich das auch.
Mit den Zahlen von oben:
1  | int16_t a = 521; // 0x209
  | 
2  | int16_t b = 732; // 0x2DC
  | 
3  | 
  | 
4  | int16_t erg = (a * b)/100;
  | 
Dieser Zwischencast auf 32 Bit bringt bei diesem Ausdruck nix, da ja 
danach wieder EXPLIZIT auf 16 Bit runtergecastet wird...
0x209 * 0x2DC = 0xD1BC.. (binaer: 1101 0001 1011 1100)
Naja in diesem Beispiel ist der Cast sowieso witzlos, da < (2^16)-1
Wie schon geschrieben funktioniert es so:
1  | int16_t erg = (int16_t) ((int32_t(a * b)) / ((int32_t)100));
  | 
Hier hat man allerdings Nachteile in der Perfomance, da 32 Bit 
Operationen auf einer 16 oder 8 Bit Maschine natuerlich deutlich laenger 
dauern.
Deshalb versuche ich aus Performancegründen zuerst immer die maximal 
moeglichen Wertebereiche abzustecken und danach die Operationen darauf 
auszulegen..
gruss