Hallo zusammen,
folgendes Problem:
ich möchte in einem größeren Projekt alle float Operationen auf integer
Operationen überführen.
Dazu habe ich mir z.B. folgende Typedefs definiert:
Gibt es irgendeine Möglichkeit, dass mich der Compiler warnt, wenn ich
z.B. folgendes machen würde:
1
f3_int32var=12345;// = 12,345
2
3
doubleFloatAusgabe_f5_int32(f5_int32Var)// Rückgabe als Float
4
{
5
return(Var/100000);
6
}
7
8
FloatAusgabe_f5_int32(var);
Dabei würde als Rückgabewert natürlich 0,12345 ausgegeben werden und
nicht 12,345. Aber der Compiler würde nicht meckern, da ich ja nur mit
zwei verschiedenen Aliasen von int32_t gearbeitet habe... Gibt es
Möglichkeiten bei so einer Fehlbenutzung eine Compiler-Warnung/Fehler zu
provozieren?
Vielen Dank schonmal und viele Grüße,
Marcel
Du könntest einen eigenen struct mit der Variable definieren, dann kann
man das nicht mehr wie einen int behandeln. Allerdings müsste man dann
bei jedem Zugriff auf die Variable im struct explizit zugreifen.
Oder wenn du C++ verwendest kannst du dir gleich eine Fixpunkt Klasse
erstellen. Da kann man dann auch die Rechenoperatoren implementieren,
damit es auch wie mit normalen Werten schreiben lässt. Verwenden ich so
auf einem Atmega.
Marcel W. schrieb:> ich möchte in einem größeren Projekt alle float Operationen auf integer> Operationen überführen.
Schau Dir mal das Q-Format an:
https://en.wikipedia.org/wiki/Q_(number_format)
Da sind vor- und Nachkommastellen binär ausgeführt, wobei die Anzahl der
Stellen wählbar ist. Es hat den Vorteil, dass bei der Re-Skalierung, die
ja nach jeder Multiplikation und Division nötig ist, nur Divisionen
durch Zweierpotenzen notwendig sind.
Zum Testen: Da kenne ich keinen Weg. Welche Skalierung Du gewählt hast,
weiss der Compiler ja nicht. Was Du natürlich testen kannst, ist ob die
Zahlen in ihrem plausiblen Wertebereich bleiben.
Marcel W. schrieb:> ich möchte in einem größeren Projekt alle float Operationen auf integer> Operationen überführen.
Wenn das nötig ist... OK.
> Dazu habe ich mir z.B. folgende Typedefs definiert:>>
Das ist nicht gerade glücklich. Wennschon Festkomma, dann nimmt man
natürlich Zweierpotenzen als interne Faktoren, alles andere ist
ziemlicher Unsinn.
> Gibt es irgendeine Möglichkeit, dass mich der Compiler warnt, wenn ich> z.B. folgendes machen würde:
[...]
Keinen Alias-Typ deklarieren, sondern einen, der tatsächlich vom
Compiler als nicht abwärtskompatibel zum Basistyp erkannt werden kann.
Das erhöht dann allerdings die Schreibarbeit ganz erheblich, weil dann
auch nicht mehr die Operatoren des Basistyps ohne Typecasts für die
Operanden verwendet werden können. Tja insgesamt ein schönes Beispiel,
warum C als Sprache eigentlich vollkommen nutzlos ist. Schafft mehr
Probleme, als es löst.
c-hater schrieb:> Tja insgesamt ein schönes Beispiel,> warum C als Sprache eigentlich vollkommen nutzlos ist. Schafft mehr> Probleme, als es löst.
So extrem würde ich es jetzt nicht formulieren, aber im Prinzip gebe ich
dir recht.
Bei meiner Fixpunkt Floatingpoint in C++ konnte ich einfach alle
bisherigen Werte durch meinen Typen ersetzen, der eine feste Anzahl von
Bits als Nachkommastellen hat. Die FFT und Filteralgorithmen sind
dadurch genauso gut lesbar wie mit floats.
Die Möglichkeit von Konstruktoren und Operatoren macht es sehr
komfortabel.
1) Automatische Umwandlung von float in Fixpunkt durch constexpr
Constructor sogar zur Compilezeit. Damit muss ich meine Werte aus meinem
Filterdesigntool nicht erst umrechnen.
2) +,-,*,/ Operatoren sind überladen und berücksichtigen den shift, ohne
dass ich bei jeder Operation selbst dran denken muss.
M.K. B. schrieb:> So extrem würde ich es jetzt nicht formulieren, aber im Prinzip gebe ich> dir recht.>> Bei meiner Fixpunkt Floatingpoint in C++ konnte ich einfach alle> bisherigen Werte durch meinen Typen ersetzen, der eine feste Anzahl von> Bits als Nachkommastellen hat. Die FFT und Filteralgorithmen sind> dadurch genauso gut lesbar wie mit floats.>> Die Möglichkeit von Konstruktoren und Operatoren macht es sehr> komfortabel.> 1) Automatische Umwandlung von float in Fixpunkt durch constexpr> Constructor sogar zur Compilezeit. Damit muss ich meine Werte aus meinem> Filterdesigntool nicht erst umrechnen.> 2) +,-,*,/ Operatoren sind überladen und berücksichtigen den shift, ohne> dass ich bei jeder Operation selbst dran denken muss.
... zum lernen als beispiel, ich würde mich über den code dazu sehr
freuen!
danke, mt
Ich habe den alten Code noch gefunden. Ob alles korrekt ist kann ich
nicht sagen, aber ich denke die Idee wird klar. Ob sich das ganze auch
bei negativen Zahlen korrekt verhält weiß ich nicht.
Zum compilieren braucht man einen Compiler, der C++11 unterstützt.
Beispiel:
Variablen vom Typ fixpoint mit gleicher Zahl Nachkommastellen lassen
sich miteinander verrechnen, wie man es von float gewöhnt ist.
Überläufe werden nicht erkannt, d.h. wenn die Zahlen zu groß werden,
gibt es keine Meldung.
Durch den constexpr Konstruktor mit float Parameter lassen sich
Kommazahlen automatisch beim Compilieren umrechnen. Ist der float Wert
eine Konstante zur Compilezeit, dann findet die Umrechnung zur
Compilezeit statt und es muss keine Software-Floatingpoint-Bibliothek
gelinkt werden.