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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Marcel W. (macew)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

assert geht niht?

Gruss

Robert

von Walter T. (nicolas)


Bewertung
0 lesenswert
nicht 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)


Bewertung
-2 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.