Forum: Mikrocontroller und Digitale Elektronik Festkommaberechnung: Compilermeldung bei Fehlbedienung provozieren, PIC18


von Marcel W. (macew)


Lesenswert?

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:
1
typedef int32_t f3_int32; // 3 interne Nachkommastellen, interner Faktor 1000
2
typedef int32_t f5_int32; // 5 interne Nachkommastellen, interner Faktor 100000

Gibt es irgendeine Möglichkeit, dass mich der Compiler warnt, wenn ich 
z.B. folgendes machen würde:
1
f3_int32 var = 12345; // = 12,345
2
3
double FloatAusgabe_f5_int32(f5_int32 Var) // 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

von M.K. B. (mkbit)


Lesenswert?

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.

von R. F. (rfr)


Lesenswert?

Hallo,

assert geht niht?

Gruss

Robert

von Walter T. (nicolas)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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:
>
>
1
> typedef int32_t f3_int32; // 3 interne Nachkommastellen, interner Faktor 
2
> 1000
3
> typedef int32_t f5_int32; // 5 interne Nachkommastellen, interner Faktor 
4
> 100000
5
>

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.

von M.K. B. (mkbit)


Lesenswert?

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.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

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

von M.K. B. (mkbit)


Angehängte Dateien:

Lesenswert?

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:
1
typedef fixedpoint::fixed_point<8 /*Nachkommastellen (Bits)*/> fixpoint_8t;
2
3
fixpoint_8t a(1.54);
4
fixpoint_8t b(2);
5
a /= b;

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.

: Bearbeitet durch User
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.