Rundungen

<< Click to Display Table of Contents >>

Navigation:  Datenmodifikation >

Rundungen

Empfohlene Einstellung zur Handhabung von Rundungen in GESStabs:

ROUNDMODE = SIMPLE; 

oder

USEEPS = YES;

Ersteres führt zur generellen Rundung von Zahlen auf die nächsthöhere Ziffer, zweiteres addiert intern ein minimales Epsilon zu einer jeden Zahl hinzu, sodass Rundungsfehler aufgrund von Kleinstwertanteilen vermieden werden.


Hintergründe zum Runden

Eigentlich ist Runden ja ganz einfach: Ab 5 nach oben, sonst nach unten. Allerdings, wenn man genauer hinschaut, ergeben sich zum einen aus der Tatsache, dass in vielen Fällen binäre floating point numbers verwendet werden, ein paar Probleme, die sich aus unvermeidbaren Ungenauigkeiten beim Wandeln von dezimalen Zahlen in binäre und umgekehrt ergeben. Zum anderen ist diese Rundungsregel wissenschaftlich nicht ganz mehr auf der Höhe der Zeit.

In GESStabs spielen binäre floating point numbers eine größere Rolle, als man vielleicht so annimmt.

Floating point numbers sind ganze negative oder positive Zahlen mit mindestens einer Dezimalstelle.

Intern sind z.B. sind auch Absolutzahlen oder Summen aus Integer-Codewerten immer floating point numbers. Ungewichtete Auswertungen z.b. sind eben nur Auswertungen auf der Basis eines Gewichts von 1.0000, aber auch 1.0000 ist eine floating point number.

Nun ergibt sich aber aus dem Unterschied zwischen der binären Darstellung und der dezimalen Darstellung, dass hier minimale Übertragungsfehler auftreten können. GESStabs übergibt die binären Rechenergebnisse, also z.b. abs. Häufigkeit / Basis * 100.0, als floating point number an die String-Routinen des Compilers. Dabei kann es sein, dass z.B. bei 130/20 intern »fast 6.5« herauskommt, so etwas wie 6.4999999999991627. Bei der »buchstabengetreuen« Anwendung der eingangs beschrieben Standard-Rundungsregel wird das auf 6 gerundet. So etwas kann durchaus bei sehr einfachen Rechnungen auftreten. Es gab etwa ein Kundenbeispiel, bei dem 484/80 berechnet wurde, und es kam binär nicht 6.05 heraus, sondern so etwas wie 6.049999999999999. Bei den Standard-Routinen des Compilers wird dann aus den 6.05 die dezimale Wiedergabe von 6.0. Dieser Rechenfehler mag beliegig klein sein, bei der Rundung zur Textdarstellung kann er leider durchschlagen.

Um das Ganze noch etwas unübersichtlicher zu machen, gibt es eine IEEE-Norm zur internen binären Darstellung von Gleit-Kommazahlen, die von der oben beschriebenen Regel abweicht. Nach IEEE-Norm (auch als Bankers Round Mode bekannt) gilt für die Fälle, die exakt zwischen den beiden ganzen benachbarten ganzen Zahlen liegen (z.B. 1.5 oder 44.5 ohne weitere Nachkommastellen), dass das Rundungsergebnis immer die am nächsten liegende gerade Zahl ist. Also: round( 1.5 ) = 2, aber round(44.5) = 44. Diese Rundungsregel liegt auch allen internen Rundungen des mathematischen Koprozessors auf Intel-Chips zugrunde. GESStabs verwendet im Prozessor immer diese Standardeinstellung: das ist 'rounding to nearest even', Rundung auf die nächste GERADE Zahl. also, 6.5 wird zu 6, 7.5 wird zu 8.

Bei den Standardroutinen zur Abbildung von Zahlen in Text wird diese Norm allerdings nicht angewendet. Das ist die historische Lage bei GESStabs nach wie vor das Standardverhalten beim Tabellieren (ROUNDMODE = CLASSIC; - siehe unten). Die klassische Lösung hierfür in GESStabs war, bei der textlichen Darstellung von Zahlen immer ein minimales Epsilon vor der Wandlung zu addieren. In der GESStabs-Syntax heißt das

USEEPS = YES;

Das ist eine Krücke, ist aber im Ergebnis ziemlich gut. Wer sie benutzt hat, hat wahrscheinlich keinerlei Probleme. Theoretisch könnte der Fall eintreten, dass ein exakter Wert von 4.49999999999995 fälschlich auf 5 gerundet wird statt auf 4. Das ist als Resultat unvermeidbar, da Rechenungenauigkeiten in dieser Größenordnung auftreten.


Roundmode

Syntax:

ROUNDMODE = [ CLASSIC | BANKERSROUNDMODE | SIMPLE ];

Default: CLASSIC

Es gibt neben dieser alten Lösung der Addition eines minimalen Ausgleichswerts mit dem oben beschriebenen ROUNDMODE zwei zusätzliche Implementierungen in GESStabs. Diese greifen bei der Bestimmung der letzten Ziffer einer Textausgabe einer Zahl. Hierfür wird der Zahlenwert durch eine Multiplikation mit einer geeigneten Potenz von 10 so umgeformt, dass ein Integerwert genau alle geforderten Stellen abbildet. Also: um 6.05 mit 1 Nachkommastelle zu berechnen, wird die Zahl mit 10 hoch 1 multipliziert. Diese Zahl (60.5) kann man in den ganzzahligen Anteil und den Rest zerlegen. Wenn dieser Rest (ziemlich genau) = 0.5 ist, haben wir exakt den Spezialfall, bei dem sich Rundung nach alter Schulmathematik und der IEEE-Norm unterscheiden. Und hier kann man jetzt mit Einstellung des ROUNDMODE Einfluss nehmen: Bei ROUNDMODE = SIMPLE; wird dann immer die nächsthöhere Ziffer gewählt, bei ROUNDMODE = BANKERSROUNDMODE; ist es die nächstgelegene gerade Zahl.

Beachte: USEEPS und ROUNDMODE sind nicht kompatibel: Wird USEEPS = YES; verwendet, sollte am ROUNDMODE nichts geändert werden. Wird trotzdem ein ROUNDMODE gesetzt, wird USEEPS intern abgeschaltet.