3

1) Ich habe viele Konstanten in meinem C Algo. 2) Mein Code funktioniert sowohl in Fließkomma als auch in Festkomma.eine Variable statisch initialisieren (zur Kompilierzeit)

Im Moment werden diese Konstanten durch eine Funktion float2fixed initialisiert, wobei sie im Gleitkomma nichts tut, während sie im Festkomma ihre Festkommadarstellung findet. Zum Beispiel bleibt 0,5f 0,5 f, wenn in Gleitkomma gearbeitet wird, während es die Routine pow() verwendet und 32768 wird, wenn in Festkomma gearbeitet wird und die Festkommadarstellung Qx.16 ist.

Das ist einfach zu warten, aber es braucht viel Zeit, diese Konstanten im Festkomma zu berechnen (pow ist eine Floatinpunkt-Funktion). In C++ würde ich eine Metaprogrammierung verwenden, also berechnet der Compiler diese Werte zur Kompilierzeit, so dass es zur Laufzeit keinen Treffer gibt. Aber in C ist das nicht möglich. Oder ist es? Kennt jemand einen solchen Trick? Ist irgendein Compiler klug genug, das zu tun?

Wir freuen uns auf jede Antwort.

A

+0

Warum können Sie nicht einfach C++ verwenden? – Zifre

+0

C unterstützt keine Preprozessor-Makros? – CookieOfFortune

+0

@CookieOfFortune: Makros sind nicht annähernd so mächtig wie C++ - Vorlagen (sie sind nicht einmal Turing abgeschlossen), aber es ist möglich. – Zifre

Antwort

0

Im Klar C, gibt es nicht viel Sie tun können. Sie müssen die Konvertierung an einem bestimmten Punkt durchführen, und der Compiler gibt Ihnen keinen Zugriff, um während der Kompilierung interessante vom Benutzer bereitgestellte Funktionen aufzurufen. Theoretisch könnten Sie versuchen, den Präprozessor zu überreden, dies für Sie zu tun, aber das ist der schnelle Weg zum totalen Wahnsinn (d. H. Sie müssten pow() in Makros implementieren, was ziemlich abscheulich ist).

Einige Optionen, die ich denken kann:

  1. einen persistenten Cache auf der Festplatte verwalten. Zumindest dann wäre es nur langsam, aber Sie müssen es immer noch laden, stellen Sie sicher, es ist nicht beschädigt, usw.

  2. Wie in einem anderen Kommentar erwähnt, verwenden Sie Vorlage metaprogramming sowieso und kompilieren mit einem C++ - Compiler. Das meiste C funktioniert gut (wohl besser) mit einem C++ - Compiler.

Hmm, ich denke, das ist alles, was ich mir vorstellen kann. Viel Glück.

2

Wenn Sie einen Festkomma-Punkt verwenden, können Sie ein Programm schreiben, das Ihre Fließkommawerte in korrekte, konstante Initialisierer für den Festkommatyp umwandelt, sodass Sie der Kompilierung, die die Festkommawerte generiert, einen Schritt hinzufügen .

Ein Vorteil davon ist, dass Sie dann Ihre Konstanten mit const definieren und deklarieren können, so dass sie sich zur Laufzeit nicht ändern - während bei den Initialisierungsfunktionen natürlich die Werte modifizierbar sein müssen, weil sie werden einmal berechnet.


Ich meine, ein einfaches Programm schreiben, das für formel Zeilen scannen, die lesen können:

const double somename = 3.14159; 

es das lesen würde und erzeugen:

const fixedpoint_t somename = { ...whatever is needed... }; 

Sie den Betrieb entwerfen zu machen Es ist einfach für beide Notationen zu verwalten - vielleicht liest Ihr Konverter die Datei immer und liest sie manchmal neu.

datafile.c: datafile.constants converter 
     converter datafile.constants > datafile.c 
+0

zu mühsam. Ich muss schon für 6 Plattformen entwickeln, und das ist nur der Anfang. – vectorizor

+1

Also, verwenden Sie gemeinsamen Code dafür - sicherlich ist das Fixpunkt-Zeug über Plattformen hinweg konstant? Wie auch immer, wenn es zu mühsam ist, dies zur Kompilierzeit zu tun, dann müssen Sie den Treffer wahrscheinlich zur Laufzeit ausführen. Viel Glück. (6 Plattformen ist nicht schlecht - das ist Routine für wo ich arbeite - und ich zähle Linux auf IA32, IA64, Itanium, zLinux, PPC als eine Plattform, nicht fünf.) –

+0

gut, nicht zu spielen, wer hat die Größtes: D, aber ich muss auf ARM, x86, GPUs laufen ... dh sehr, und schmerzlich, verschiedene CPUs. Gewinne ich? :) – vectorizor

4

Anstatt (unsigned)(x*pow(2,16)) mit Ihrer festen Punkt Umwandlung zu tun, schreiben Sie es als (unsigned)(0.5f * (1 << 16))

Dies sollte ein akzeptabler als Übersetzungszeit konstanter Ausdruck sein, da sie nur gebautet Betreiber handelt.

+0

sehr gute Idee in der Tat! – vectorizor

1

Neuere Versionen von GCC (etwa 4.3) haben die Möglichkeit hinzugefügt, GMP und MPFR zu verwenden, um einige Kompilierungszeitoptimierungen durchzuführen, indem komplexere Funktionen, die konstant sind, ausgewertet werden. Dieser Ansatz lässt Ihren Code einfach und portabel und vertraut dem Compiler, das schwere Heben zu tun.

Natürlich gibt es Grenzen, was es tun kann, und es wäre schwer zu wissen, ob es eine bestimmte Instanz optimiert, ohne die Baugruppe zu betrachten. Aber es könnte einen Besuch wert sein. Here's a link to the description in the changelog

+0

Aber es wäre portierbar nur zu dem Punkt, wo der Compiler, den Sie portieren, die gleichen Optimierungen unterstützt. Andernfalls kann es für die andere Plattform kompilieren, aber die Laufzeitleistung ist möglicherweise inakzeptabel. Stellen Sie sich vor, Sie würden etwas auf ein eingebettetes System mit einem Compiler portieren, der die erweiterten GCC-Optimierungen nicht unterstützt. – VoidPointer