🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: de.comp.lang.c++
Article #1917

Re: Fehler in der floor()-Routine aus math.h ?

#1917
From: Dietmar Kuehl
Date: Tue, 26 Mar 1996 19:30
61 lines
3193 bytes
Hi,
Jörg-Peter Reich (reich@rummelplatz.uni-mannheim.de) wrote:
: Bei manchen Zahlen errechnet die 'floor()'-Routine aus
: 'math.h' falsche Ergebnisse.  Der Fehler scheint nicht
: rechnerabhängig zu sein (tritt bei Pentium und 486er
: gleichermaßen auf).  Auch verschiedene Versionen des
: Borland-C++-Compilers machen immer denselben Fehler.

Das liegt vermutlich daran, dass sich verschiedene Hardware-Hersteller
an gaengig IEEE Spezifikationen halten. Deren Floating-Point
Definitionen werden normalerweise verwendet.

: #include<iostream.h>
: #include<math.h>

: int main()
: {
:   double x = 6.4 / 0.8;
:   double y = 4.8 / 0.8; // Ausgabe:
:   cout<<x<<endl;        // "8"  (ok)
:   cout<<y<<endl;        // "6"  (ok)
:   cout<<floor(x)<<endl; // "8"  (ok)
:   cout<<floor(y)<<endl; // "5"  (falsch !)
:   return 0;
: };

: Ich nehme an, daß rechnerintern anstatt 4.8 / 0.8 = 6
: ein Wert etwas kleiner als 6 rauskommt.  Aber mit dieser
: Erkenntnis ist mir nicht geholfen. Weiß irgendwer weiter ???

Da Floating-Point Rechnungen noch nie exakt waren und auch in Zukunft
aller Wahrscheinlichkeit nach nicht exakt sein werden (ich koennte mir
vorstellen, dass man mit analogen Computern exakt rechnen kann; mit
digitalen Rechnern geht es auf jeden Fall nicht), bleibt Dir nichts
anderes uebrig, als damit zu leben und die Erkenntnis, dass sich der
Computer (leicht) verrechnet hat zu nutzen.

z.B. kann man die Werte wieder etwas groesser machen, bevor man sie
nach unten rundet (in der Annahme, dass man, wenn man sich verrechnet
hat, lieber zum naechsten Wert kommt...):

  #include <float.h>
  cout << floor(y + 10 * DBL_EPSILON) << endl;

'DBL_EPSILON' ist die Distanz, zwischen zwei aufeinanderfolgenden
'double' Werten. Da sich der Computer vermutlich um mehr als diesen
Wert irrt, wird etwas mehr Spielraum (in diesem Fall eine
Groessenordnung) eingeraeumt. Fuer Applikationen, die numerisch stabil
sein sollen, muss der Spielraum typischerweise wesentlich groesser
gemacht werden (z.B. fuer eine Implementation des revidierten
Simplex-Verfahrens habe ich gute Ergebnisse erreicht, wenn der
Spielraum ca. 6 Groessenordnungen umfasste). Die Idee ist einfach, dass
man zwei Zahlen als gleich ansieht, wenn sie innerhalb einer
"Epsilon-Umgebung" liegen. Das ist bei Floating-Point Rechnungen
grundsaetzlich notwendig, eben weil die Rechnungen nicht exakt sind und
bei digitalen Computern auch nicht exakt sein koennen (Informatik
Grundstudiumsvorlesung, 1.Semester...).
--
dietmar.kuehl@uni-konstanz.de
http://www.informatik.uni-konstanz.de/~kuehl
I am a realistic optimist - that's why I appear to be slightly pessimistic
Technical Details
Message-ID: <4j9gks$8vc@news.BelWue.DE>
Path: arc1-ca.pugleaf.net!news.belwue.de!uzwil!kuehl
References: <31582625.75EE@rummelplatz.uni-mannheim.de>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!news.belwue.de!uzwil!kuehl
From: kuehl@uzwil.informatik.uni-konstanz.de (Dietmar Kuehl)
Newsgroups: de.comp.lang.c++
Subject: Re: Fehler in der floor()-Routine aus math.h ?
Date: 26 Mar 1996 19:30:36 GMT
Organization: Fakultät für Mathematik und Informatik
Message-ID: <4j9gks$8vc@news.BelWue.DE>
References: <31582625.75EE@rummelplatz.uni-mannheim.de>
Reply-To: dietmar.kuehl@uni-konstanz.de
NNTP-Posting-Host: uzwil.informatik.uni-konstanz.de
X-Newsreader: TIN [version 1.2 PL2]