Thread Subtrahieren in Perl (Fließkomma, aber genau) (20 answers)
Opened by EdisonR1 at 2013-09-23 16:52

topeg
 2013-09-23 22:52
#170539 #170539
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Bei Fließkommazahlen werden Werte in Matrisse und Exponent gespeichert. Die Basis ist heutzutage 2.
Also ein Zahl wird so gespeichert: <matrisse>*2^<exponent>.
Wäre die als Matrisse und Exponent speicherbare Zahl beliebig groß, so könnte man jede beliebige Zahl darstellen.
Doch gibt es durch den verwendeten Prozessor auferlegte grenzen.
In modernen Computern gibt es im allgemeinen den Datentyp "Float" um Fließkommazahlen zu speichern. Er hat 32Bit. Da ist die Matrisse 23Bit und der Exponent 8Bit. Ein Bit wird noch gebraucht um das Vorzeichen darstellen zu können. Dann gibt es noch "Double" (64Bit) und "long Double" (80-128Bit). bei 64Bit Prozessoren entspricht das Float meist einem Double.
Mit solchen Werten kann die Fließkommaeinheit des Prozessors noch effizient rechnen.
Diese Begrenzungen sorgen dafür das nicht jede beliebige Zahl dargestellt werden kann. Die Ungenauigkeiten kommen genau daher. Das Ergebnis der Rechnung oder die Ausgangswerte sind nicht als Fließkommazahlen darstellbar.

Wie kann man das Problem umgehen.
  • Was heutzutage am häufigsten gemacht wird ist die nicht die volle Spanne der der Fließkommazahlen zu benutzen. Man rechnet in einem sicheren "Bereich". Praktisch heißt das, man rundet das Ergebnis auf auf die Stellen die man braucht.
  • Wenn man den Wertebereich gut genug Einschränken kann, kann man mit Festkommawerten rechnen und passend runden, wenn es nötig ist.
  • Man kann Größere Zahlen erlauben indem man die Anzahl der Bits, die eine Zahl speichern erhöht. Der Nachteil ist, das man dem Prozessor damit viel Arbeit macht. Diese können Zahlen nicht mehr mit der Fließkommaeinheit des Prozessors bearbeitet werden. Da muss der Prozessor "von Hand" ran. Das kann den Aufwand für eine einfache Addition leicht verzehnfachen, Divisionen können 100 mal so lange dauern.
  • Man kann Symbolisch Rechnen. Der ganze Zweig des symbolischen Rechnen ist aus genau dem Grund entstanden, das Computer Zahlen nicht immer exakt Darstellen können. Die Idee ist im Programm eine Formel aufzustellen und sie dann vom Computer soweit auflösen zu lassen, das er sie möglichst ohne Fehler berechnen kann. Fehler erzeugende aber überflüssige Rechnungen werden so vermieden.


Was genau du machst hängt von deinen Anforderungen ab.
In einem der anderen Beiträgen dazu habe ich gezeigt wie man korrekt Runden kann. Der Trick dabei ist ein ähnlicher wie es auch das Modul Math::BigFloat macht. Ich zerlege den Wert in Matrisse und Exponent und benutze jeweils 32-bit Werte um jedes zu speichern. Damit ist die Auflösung/Wertebereich Erhöht und RundungsFehler tauchen nicht mehr auf (Wenn man genügend große Werte wählt stößt auch diese Funktion an ihre Grenzen). Das ich die Basis 10 genommen habe ist einfach Gewohnheit.

View full thread Subtrahieren in Perl (Fließkomma, aber genau)