double gleich 0 geht net??
-
habe leider einen fehler gemacht, es müsste wohl heißen
if(std::abs(y) <= std::numeric_limits<double>::epsilon())
std::abs() liefert den absoluten betrag von y (kehrt bei negativen zahlen das vorzeichen um). epsilon() liefert den kleinsten wert, den man zu 1.0 hinzuaddieren kann, um eine von 1.0 verschiedene zahl zu erhalten.
sinn des ganzen ist es, die systembedingten rundungsfehler bei gleitkommazahlen zu umschiffen. dazu nimmt man einfach an, dass zahlen, die hinreichend nahe an 0 herankommen, mit 0 identisch sind.
siehe http://de.wikipedia.org/wiki/IEEE_754
ich hoffe dass die anwendung von epsilon() so richtig ist, wenn nicht bitte ich um korrektur.
-
In dem Ursprünglichen Post sind 2 Fehler
1.) if( y==0 ) ist ein Vergleich mit einem Integer, die Kommastellen werden also nicht berücksichtigt. Deshalb (y==0.0) wenn schon.
2.) Wie die anderen schon geschrieben haben, soll man das so überhaupt nicht machen, weil Fließkommazahlen eben nicht genau sind.
Allerdings ist in der Lösung im letzten Post auch noch ein Fehler. abs() ist nur für Integer definiert und liefert int zurück. Korrekterweise muss hier fabs() verwendet werden.
-
bool equals( const double& a, const double& b ) { return ! ( std::fabs(a-b) > std::numeric_limits<double>::epsilon() ); }
-
Dein X - Intervall ist zu groß.
Ausserdem macht man sowas mit geeigneten Verfahren wie das Newtonverfahren, Regula Falsi, etc.
-
Gleitkommanzahlen kann man nie auf Null abfragen, sondern stets auf einen
Absolutbetrag kleiner einer gewünschten Grösse. Mehr ist dazu nicht zu sagen.
-
berniebutt schrieb:
Gleitkommanzahlen kann man nie auf Null abfragen, sondern stets auf einen
Absolutbetrag kleiner einer gewünschten Grösse. Mehr ist dazu nicht zu sagen.warum nicht
-
berniebutt schrieb:
Gleitkommanzahlen kann man nie auf Null abfragen, sondern stets auf einen
Absolutbetrag kleiner einer gewünschten Grösse. Mehr ist dazu nicht zu sagen.So ganz pauschal ist das auch nicht richtig.
Bei Fließkommazahlen gilt schon, dass 0.0 == 0.0, aber es gilt u.U. nicht (ich hab es jetzt nicht nachgerechnet), dass 0.5 * 6 - 3 = 0.0.
Der Grund ist der, dass diese Zahlen ja auch nur diskret sind, es gibt nur eine begrenzte Anzahl disjunkter Zustände in einem Intervall, wohingegen es bei "echten" reellen Zahlen unendliche viele verschiedene Zahlen pro Intervall gibt.
Für die Praxis heißt das, dass man in aller Regel nicht direkt auf Gleichheit prüfen sollte, sondern wie oben gezeigt auf eine Abweichung.
Eine Ausnahme ist aber z.B. folgender Fall:
float f = 0.0; if (sunIsShining()) { f = 47.11; doSomethingWithF(f); doSomethingMore(); } doVeryMuchMore(); if (f == 0.0) {}
Über guten Stil kann man natürlich streiten, aber in dem Fall kann man davon ausgehen, dass der Vergleich auf Null erfolgreich ist, wenn f weiter oben nicht verändert wurde.
-
y = a*x*x*x*x*x+b*x*x*x*x+c*x*x*x+d*x*x+e*x+f;
Wuah, wenn schon, dann so etwas:
y = ((((a*x+b)*x+c)*x+d)*x+e)*x+f;
-
Walli schrieb:
y = a*x*x*x*x*x+b*x*x*x*x+c*x*x*x+d*x*x+e*x+f;
Wuah, wenn schon, dann so etwas:
y = ((((a*x+b)*x+c)*x+d)*x+e)*x+f;
Unlustig
Das schreibt nach pow!
-
Die Frage war doch nur, warum eine berechnete Gleitkommazahl nicht auf identisch 0.00 abgefragt werden kann. Diese Frage ist hinreichend beantwortet. Und denkt an die vielen Programmierer, die unbeabsichtigt eine "dead do loop"
programmiert hatten und ohne debug nicht einmal wussten wo!!!
-
dsfsdf schrieb:
Walli schrieb:
y = a*x*x*x*x*x+b*x*x*x*x+c*x*x*x+d*x*x+e*x+f;
Wuah, wenn schon, dann so etwas:
y = ((((a*x+b)*x+c)*x+d)*x+e)*x+f;
Unlustig
Das schreibt nach pow!
Geh spielen!