Forum: PC-Programmierung [C/C++] Korrekt rechnen mit/ohne #inf


von Anfänger (Gast)


Lesenswert?

Hallo liebe Forengemeinde,

für ein Projekt muss ich einige mathematische Formeln in C/C++ (Visual 
Studio und doubles) umsetzen. In den Formeln kann der Fall auftreten, 
dass z.B. in einem Bruch durch 0 geteilt wird. Das Ergebnis ist 
natürlich #inf, womit ich gut leben könnte.

In einer späteren Formel kann also der Fall auftreten, dass zweier 
dieser Zahlen voneinander subtrahiert werden. Ich würde behaupten, dass 
#inf-#inf=0 sind. Das tatsächliche Ergebnis ist jedoch #IND, also 
undefiniert.
Dies führt dazu, dass die Ergebnisse weiterer Berechnungen unbrauchbar 
werden.

Ich habe bisher immer gedacht, dass C/C++ in der Lage ist mit diesen 
Symbolen umzugehen, doch scheinbar bin ich auf dem Holzweg. Als 
Workaround habe ich in den Nenner der Brüche ein "+ 1e-100" eingefügt, 
um keine glatte 0 zu erhalten.

Daher die Frage an die Gemeinde:
Wie geht man tatsächlich mit diesen Grenzfällen in C/C++ um? Gibt es 
evtl. eine Compileroption, um die Rechnung mit den Symbolen zu 
ermöglichen? Quellen und Literatur sind natürlich ebenfalls gerne 
gesehen.

Gruß, Anfänger

P.S.
Im späteren Verlauf sollen diese Rechnungen evtl. in einen PIC 
einprogrammiert werden, daher würde ich Lösungen für C bevorzugen.

von Michael P. (mipo)


Lesenswert?

Na ja, letztlich ist #INF bzw. #IND ein spezielle "Wert" in der 
double-Darstellung, der signalisiert "hier stimmt was nicht".

Den kannst Du übrigens in #include <limits> finden:
1
#include <limits>
2
  double inf = std::numeric_limits<double>::infinity();

Ist auch als Makro in <cmath>, siehe 
http://www.cplusplus.com/reference/cmath

Damit kannst Du die Fälle im Code ggfs abfragen und entsprechend 
reagieren.

Daneben spielt aber auch die Compiler-Einstellung für Fließkommazahlen 
eine Rolle, schau mal in der Online-Hilfe von VS

von Daniel A. (daniel-a)


Lesenswert?

> in einem Bruch durch 0 geteilt wird.
Hier muss angesetzt werden! Wärent das bei integern zum programmcrash 
führt, ist bei float das verhalten undefiniert! Wenn du soetwas machen 
willst, dann nimm Java,JavaScript,etc., dort ist ein ganz bestimtes 
Infinity-kompatibles format für float forgeschrieben.

von Karl H. (kbuchegg)


Lesenswert?

Anfänger schrieb:

> In den Formeln kann der Fall auftreten,
> dass z.B. in einem Bruch durch 0 geteilt wird. Das Ergebnis ist
> natürlich #inf, womit ich gut leben könnte.

Nope.
Damit kannst du eben NICHT gut leben.

Wenn der Fall auftritt, dass du durch 0 dividierst, dann musst du den 
abfangen und speziell behandlen. Alles andere, insbesondere das 
ignorieren dieser Fälle, ist Mumpitz, auch wenn dein Programm im Falle 
von double Berechnungen nicht gleich abschmiert.

> In einer späteren Formel kann also der Fall auftreten, dass zweier
> dieser Zahlen voneinander subtrahiert werden.

Nein, dieser Fall kann nicht auftreten. Denn du hast im Vorfeld schon 
dafür gesorgt, dass es gar nicht bis zu dieser Berechnung kommt, sondern 
das Programm den Fall, das durch 0 zu dividieren versucht wird erkennt 
und die Berechnung abbricht und der Fehlerfall entsprechend auf höherer 
Ebene behandelt wird.

Divisionen durch 0 sind kein Kavaliersdelikt, das man wegen 
Geringfügigkeit nicht zu behandeln braucht.


Ich denke, was du gerade im Begriff bist zu lernen das ist, das 
Programmieren an sich nicht leicht ist, das aber Fehlerbehandlung 
integraler Bestandteil der Programmierung ist und es nicht ungewöhnlich 
ist, dass Fehlerbehanldung einen nicht unbeträchtlichen Teil eines 
Programmes ausmacht. Der nebenbei bemerkt, oft gar nicht so trivial ist, 
wie allgemein angenommen. Denn nicht immer sind die Dinge so klar, wann 
es eigentlich zu einem Problem gekommen ist. Ganz speziell dann nicht, 
wenn Floating Point im Spiel ist.

: 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.