🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.c++
2 messages
2 total messages Started by Jörg-Peter Reich Tue, 26 Mar 1996 17:15
Fehler in der floor()-Routine aus math.h ?
#1916
Author: Jörg-Peter Reich
Date: Tue, 26 Mar 1996 17:15
33 lines
1371 bytes
Hi,

ich hab folgendes Problem:

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.



#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 ???

(email: reich@rummelplatz.uni-mannheim.de)

Ciao,  Jörg.  :-(
Re: Fehler in der floor()-Routine aus math.h ?
#1917
Author: 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
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads