Hallo Leute,
ich habe eine Frage, vielleicht könnt ihr mir weiterhelfen.
Ich verwende: AVR Studio 6.2 mit AVR8_Toolchain_Version:3.4.4.1229
GCC_VERSION:4.8.1.
Ich habe eine Funktion um eine Line zwischen zwei Punkten zu berechnen.
Dabei berechne ich die Steigung vor der Schleife um Divisionen zu
vermeiden. Um den Compiler zu bewegen, erst die Multiplikation und dann
die eine Division auszuführen, habe ich die Zwischenwertvariable als
volatile definiert. Es treten keine Überläufe auf und x2 ist immer
größer als x1.
1 | void line(int16_t x1, int16_t y1, int16_t x2, int16_t y2) {
|
2 | ...
|
3 | volatile int32_t a;
|
4 | ...
|
5 | a=(y2-y1)*16384;
|
6 | a=a/(x2-x1);
|
7 | ...
|
8 | for(x=0;x<(x2-x1);x++) {
|
9 | b=a*x;
|
10 | set_pixel(abs(x1+x),abs((b/16384)+y1));
|
11 | }
|
In dem einfachen Beispiel line (0,0,200,20) geht das aber nicht, denn a
bleibt immer 0.
Wenn ich aber anstelle a=(y2-y1)*16384;
a=(y2-y1);
a=a*16384;
verwende, was ja im Prinzip das gleiche ist, funktioniert es bestens.
Ich habe mir schon den Wolf gesucht und den Workaround beim Debuggen
gefunden. Ein ähnlichen Problem tritt auf, wenn ich in der Schleife den
y Wert direkt nach der Geradengleichung berechne:
a=(y2-y1)/(x2-x1)*x;
Das Ergebnis ist immer falsch. Eigentlich sollten doch alle Berechnungen
als 32 bit integer ausgeführt werden, oder?
Ist das ein generelles CPP Problem oder hat das nur der AVR GCC. Ich
habe schon mit älteren Versionen des AVR GCC gearbeitet aber bisher noch
solche Probleme gehabt.
Danke für Hinweise! Grüße Jörg