Hallo, wollte mir vom Präprozessor eigentlich gemütlich den Vorteiler
bei ATmega ausrechnen lassen, nur bin ich scheinbar an die Grenze meiner
Fähigkeiten bzw. Verständnis vom Präprozessor angelangt.
Alex (ein anderer ...) wrote:
> Per default interpretiert die Präprozessor jede Zahlenkombination als> integer, es sei denn du sagst ihm was anderes.
Der Präprozessor kann ausschließlich Integer-Rechnung.
> #define WISHED_TIME1 (0.01f)
Was soll'n das für eine Sprache sein? C jedenfalls nicht.
Alex (#1), bedenke, dass der Präprozessor in allererster Linie Makros
ersetzt. Dein (1/100) wird also genau so in die entsprechenden
Ausdrücke eingesetzt. Falls ein Ausdruck innerhalb eines #if auftaucht,
wird er nach normalen Integerregeln berechnet.
ergibt also (mal F_CPU = 1000000ul angenommen)
( ( (1000000ul / 8) * (1/100)) <= 0x000FFFFUL)
Da du das 1/100 geklammert hast, muss dieser Teilausdruck immer zuerst
berechnet werden, und ergibt letztlich (Integer-Rechnung) die Konstante
0. Das ist sicher nicht, was du wolltest. ;-)
Lässt du die Klammern weg:
1
#define WISHED_TIME1 1/100
so ergibt die Ersetzung:
( ( (1000000ul / 8) * 1/100) <= 0x000FFFFUL)
In diesem Falle wird zuerst 1000000ul / 8 berechnet (ergibt 125000ul),
danach mit 1 multipliziert (immer noch 125000ul), dann durch 100
dividiert (12500ul), dann verglichen. Sieht mir eher nach dem aus,
was du erreichen wolltest, nicht wahr? Natürlich ist das ziemlich
riskant, mit solchen ungeklammerten Ausdrücken bewusst die
Auswertungsreihenfolge zu ändern, ist aber bei Integer-Rechnung deine
einzige Chance (wenn du nicht gerade Zähler und Nenner in separate
Makros legen willst).
OT: "wished" sollte in diesem Zusammenhang besser "desired" heißen.
Die Amis würden es aber wohl eher TARGET_TIME1 nennen.
Mein g++ sorgt dafür, dass in foobar der Wert 0.01 landet ...
Hier rechnet dann wohl der Compiler für mich?
Wäre ein Compiler dann auch in der Lage ein (if - else if - else)
Kontrukt in dessen bedingten Ausdrücken nur Compile-Zeit Konstanten
verwendet werden aufzulösen (wegzuoptimieren)?
Dann könnte man den Präprozessor komplett aus dem Spiel lassen.
Alex (ein anderer ...) wrote:
> Mein g++ sorgt dafür, dass in foobar der Wert 0.01 landet ...
Sorry, dass 0.01f kein gültiges C sei, nehme ich hiermit zurück.
Da man das Feature nur äußerst selten braucht, hatte ich den Suffix
f für die Unterscheidung zwischen float- und double-Konstanten
einfach vergessen. 0.01 ist double, 0.01f ist float.
> Hier rechnet dann wohl der Compiler für mich?
Ja.
> Wäre ein Compiler dann auch in der Lage ein (if - else if - else)> Kontrukt in dessen bedingten Ausdrücken nur Compile-Zeit Konstanten> verwendet werden aufzulösen (wegzuoptimieren)?
Wenn du die Optimierung einschaltest, ja.
> Dann könnte man den Präprozessor komplett aus dem Spiel lassen.
Ja, für solche Fälle kann man sie aus dem Spiel lassen. Andererseits
lassens sich mit Präprozessor-Konstruktionen oft bestimmte Dinge in
Headerfiles gut abstrahieren, sodass sie dann nicht den eigentlichen
Code mit totem Code ,,verschandeln''. Dadurch kann die Übersichtlich-
keit besser werden.
Danke erstmal fuer die Antworten, das der Praeprozessor nur integer
Rechnen kann war mir nicht bewusst und damit ist mir nun auch klar waran
es haengt. Klammer weglassen waere wirklich die schlechteste Loesung,
daher werde ich wohl eher versuchen die TARGET_TIME1 :) in ms
auszudruecken und zukuenftig auch bei Praeprozessor Rechnungen
Rundungseffekte mit bedenken. Andere Variante waere sicherlich das
"normal" in Variablen rechnen zu lassen und dann den Compiler zu nutzen
um dies wegzuoptimieren. Fuer mich ist die bewusste
Compilerwegoptimierung doch noch etwas undurchsichtig. Ich habe mich
bisher damit noch nicht so intensiv auseinandergesetzt, um im Vorfeld zu
wissen was der Compiler in welche Stufe alles wegoptimiert.
Optimierungen sehe ich fuer mich momentan eher um gut lesbaren und
verstaendlichen Code schreiben zu koennen und trotzdem Groessen und
Geschwindigkeitsmaessig etwas mithalten zu koennen.
Gruss Alex
Peter Dannegger wrote:
> Man kann mit float nur rechnen lassen, aber keine Tests durch den> Präprozessor machen.
Die Rechnung erledigt aber der Compiler. Es ist ein weit verbreiteter
Irrtum, dass der Präprozessor die Konstanten-Eliminierung vornehmen
würde, nur weil man die Konstanten gerade in einem Präprozessormakro
hinterlegt hätte.
Der Präprozessor ersetzt Texte, sonst macht er (fast) nichts.
Eigene Ausdrücke berechnet er nur in einem #if-Test.
Der Name des Headerfiles ist übrigens seit mehr als 5 Jahren
<avr/io.h>, und der Wrapper <io.h> existiert bereits seit 3 Jahren
nicht mehr. Peter, deine ,,Altmodigkeit'' in allen Ehren, aber bitte
empfehle Leuten, die hier unbedarft rangehen nichts, was nur in deinem
auf steinzeitliche Rückwärtskompatibilität getrimmten Setup
funktioniert.
Die Benutzung von xor zum Verknüpfen der Vorteilerbits bzw. der Vorteil
gegenüber dem (einschließlichen) oder erschließt sich mir ganz und gar
nicht.
Jörg Wunsch wrote:
> Peter Dannegger wrote:>>> Man kann mit float nur rechnen lassen, aber keine Tests durch den>> Präprozessor machen.>> Die Rechnung erledigt aber der Compiler.
Ich denke, dass er das meinte... ;)
Zumindest kann ich mir nichts anderes vorstellen.
Simon Küppers wrote:
> Ich denke, dass er das meinte... ;)
Ja, wenn ich mir's nochmal durchlese, wirst du wohl Recht haben. Aber
irgendwie so seltsam formuliert, dass ich es beim ersten Lesen wohl
nicht wirklich geschnallt habe...
Jörg Wunsch wrote:
> Die Benutzung von xor zum Verknüpfen der Vorteilerbits bzw. der Vorteil> gegenüber dem (einschließlichen) oder erschließt sich mir ganz und gar> nicht.
Das ^ läßt sich leichter tippen, man muß nicht 2 weit entfernte Tasten
drücken (AltGr rechts, | links).
Die obigen Berechnungen werden sogar bei -O0 zusammengefaßt.
Peter
Peter Dannegger wrote:
> Jörg Wunsch wrote:>>> Die Benutzung von xor zum Verknüpfen der Vorteilerbits bzw. der Vorteil>> gegenüber dem (einschließlichen) oder erschließt sich mir ganz und gar>> nicht.>> Das ^ läßt sich leichter tippen, man muß nicht 2 weit entfernte Tasten> drücken (AltGr rechts, | links).
Peter, ist das dein Ernst? ... *räusper
Simon Küppers wrote:
>> Das ^ läßt sich leichter tippen, man muß nicht 2 weit entfernte Tasten>> drücken (AltGr rechts, | links).>> Peter, ist das dein Ernst? ... *räusper
Vollster ernst, warum soll man denn keine Tipparbeit sparen?
Das "avr\" spare ich mir ja auch.
Peter
in c++ sind ja in den templates auch floating point
ausdrücke verboten. wenn ich mich richtig erinnere
war die begründung, dass je nach compiler/maschine
die compile time berechnungen anders ausfallen würden.
man denke auch an die crosscompilationen.
Bei den #define makros meine ich, dass die floating
point berechnungen zur runtime ausgeführt werden.
All die makros würden per textersetzung einfach
eingesetzt und fertig.
gruss, daniel
man denke auch an die crosscompilationen.
damit meine ich, dass die maschine auf der compiler läuft,
anders fliesskommazahlen berechnet als die maschine
auf der complierte code später abläuft.