Forum: PC-Programmierung Konstanten Arithmetik in C


von rmf (Gast)


Lesenswert?

Hallo miteinander,

nach längerer ergebnisloser Suche im Netz dachte ich mir ich frage mal 
nach euer Meinung.

Gibt es eine Norm/Vorschrift wie ein C Compiler berechnungen mit 
Konstanten umsetzen soll?

Beispiel:

#define WERT1 1.23
#define WERT2 100UL
:
:
unsigned char ucWert3;
unsigned char ucResult;

ucWert3 = 2;
ucResult = ucWert3 + (WERT1 * WERT2);

Mir scheint manche Compiler gehen her berechnen zuerst WERT1 * WERT2, 
wandeln diesen konstanten Teil der Formel in einen Integer (zur Compile 
Zeit) um, und setzen diesen Int dann im Programm ein.
Andere Compiler machen zur Laufzeit des Programms eine Float nach int 
Umwandlung was natürlich Code und Laufzeit kostet.

Die Handbücher geben auch nichts dazu her.

Wie sind eure Erfahrungen dazu?

Gruß Udo

von DirkB (Gast)


Lesenswert?

Da WERT1 ein float ist, erfolgt die Berechnung von (WERT1 * WERT2) als 
double.
Somit ist das Ergebnis der Klammer auch ein double.
Das macht der Compiler, je nach Optimierung, auch schon zur Compilezeit.

Die Berechnung von ucWert3 * () ist dann auch in double.

Das ist so vom Standard vorgeschrieben.

von Karl H. (kbuchegg)


Lesenswert?

rmf schrieb:

> Gibt es eine Norm/Vorschrift wie ein C Compiler berechnungen mit
> Konstanten umsetzen soll?

Nach den C-Regeln zur Bewertung von Ausdrücken und der obersten 
Optimier-Direktive 'as if'.

D.h. der Compiler darf alles optimieren, solange es sich im Ergebnis 
nicht davon unterscheidet, wie ein Programm das zur Laufzeit berechnet 
hätte. Inklusive aller Datentypwandlungen, inklusive aller 
möglicherweise auftretenden Overflows.

Alles mit Floating Point war/ist insofern ein Problem, weil der 
Compiler, wenn er eine Floating Point Berechnung mittels Constant 
Folding wegoptimiert, Bit für Bit ein identisches Ergebnis rausbringen 
muss, wie es auch die Hardware produzieren würde, wenn sie dann die 
Berechnung durchführt. Und das war früher gar nicht so einfach, wenn da 
eine dezidierte FPU im Spiel war, die wieder abweichende Floating Point 
Formate benutzte, als zb die Software-Implementierung der entsprechenden 
Funktionalität.

Man beachte: Er darf!
Nicht: Er muss!

: Bearbeitet durch User
von rmf (Gast)


Lesenswert?

Vielen Dank für die Infos,

das hilft mir schonmal weiter.

Udo

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Um sicherzugehen, caste den konstanten Teil:

ucResult = ucWert3 + (uint8_t) (WERT1 * WERT2);
                        ^
                        |
                        -- oder einen anderen sinnvollen Typ

Dann werden auch keine float-libs herangezogen. Ich mache das im 
IRMP-Source viele dutzendmal. Ist dann überhaupt kein Problem.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.