ABAP - Schlüsselwortdokumentation →  ABAP - Referenz →  Interne Daten verarbeiten →  Numerische Berechnungen → 

Numerische Datentypen

ABAP unterstützt die numerischen Datentypen: i, int8, p, decfloat16, decfloat34 und f, sowie die internen Typen b und s. Die letzteren können nicht direkt in Programmen angegeben werden, entstehen aber bei Bezug auf die eingebauten Typen INT1 bzw. INT2 des ABAP Dictionary. Sie werden in der Regel analog zu Typ i verwendet und intern häufig nach i konvertiert.

Die numerischen Datentypen dienen der Aufnahme von Zahlenwerten und sind für Rechenoperationen vorgesehen. Rechenoperationen für Felder vom Typ i, int8 und Typ f können praktisch direkt auf Maschinenbefehle des Betriebssystems des aktuellen Applikationsservers abgebildet werden. Dagegen ist das Rechnen mit gepackten Zahlen vom Typ p im Kernel der ABAP-Laufzeitumgebung realisiert, also etwas langsamer. Die Operationen mit den dezimalen Gleitpunktzahlen decfloat16 und decfloat34 werden solange über eine in den ABAP-Kernel integrierte Bibliothek ausgeführt, bis sie von der Hardware des Applikationsservers unterstützt werden.

Der gemeinsame generische Typ der numerischen Datentypen ist numeric.

Programmierrichtlinie

Wahl des numerischen Typs

Hinweise

Integer-Zahlen

Die Datentypen für Integer-Zahlen i und int8 haben einen Wertebereich von -2147483648 bis +2147483647 für i und -9.223.372.036.854.775.808 bis +9.223.372.036.854.775.807 für int8 und umfassen nur ganze Zahlen. Integer-Zahlen vom Typ i können als Zahlenliteral direkt im Programm angegeben werden.

Alle Zwischenergebnisse eines arithmetischen Ausdrucks vom Rechentyp i oder int8 werden in Hilfsfeldern vom Typ i bzw. int8 abgelegt. Ansonsten verhält sich die Arithmetik des Typs i bzw. int8 wie die des Typs p ohne Nachkommastellen. Insbesondere wird bei der Division gerundet und nicht abgeschnitten, und ein Überlauf führt zu einer Ausnahme. Der Datentyp Typ i und int8 wird typischerweise für Zähler, Anzahlen, Indizes, Offsets sowie Zeitspannen verwendet.

Hinweis

Mit den Datentypen b, s, i und int8 liegt ein kompletter Satz Datentypen für 1-, 2-, 4- und 8-Byte-Integer-Zahlen vor. Die Typen b und s für kurze Integer-Zahlen können in ABAP-Programmen aber nicht direkt sondern nur über den Umweg der eingebauten Typen INT1 und INT2 aus dem ABAP Dictionary angegeben werden. Sie haben auch keinen eigenen Rechentyp.

Beispiel

Typische Verwendung des Datentyps i.

DATA counter TYPE i.
...
counter = counter + 1.
...

Gepackte Zahlen

Der Datentyp für gepackte Zahlen p hat einen Wertebereich, der von der Länge sowie der Anzahl der Nachkommastellen abhängt. Datenobjekte vom Typ p können 1 bis 16 Bytes lang sein, wobei in jedes Byte zwei Stellen gepackt werden und in das letzte eine Stelle und das Vorzeichen. Eine gepackte Zahl besteht aus zweimal der Länge minus eins Ziffern und kann bis zu 14 Nachkommastellen haben. Gepackte Zahlen realisieren Festpunktzahlen. Die Nachkommastellen einer gepackten Zahl sind eine Eigenschaft ihres Datentyps und für diesen fest vorgegeben.

Gepackte Zahlen mit Nachkommastellen können im Programm nicht direkt angegeben werden. Statt dessen muss man Zeichenliterale verwenden, deren Inhalt als gepackte Zahl interpretiert werden kann, d.h. eine Zahl in mathematischer oder kaufmännischer Notation darstellt. Die wissenschaftliche Notation ist nicht zulässig, es sei denn, sie ist als mathematische Notation interpretierbar.

Hilfsfelder für Zwischenergebnisse in arithmetischen Ausdrücken vom Rechentyp p sind standardmäßig immer 16 Bytes lang, können also bis zu 31 Stellen aufnehmen. Vor einem Überlauf wird ein arithmetischer Ausdruck nochmals mit doppelt so großen Hilfsfeldern bzw. 63 Stellen berechnet. Bei Vergleichen zwischen gepackten Zahlen wird der Operand mit weniger Nachkommastellen ebenfalls in ein solches Hilfsfeld konvertiert, wobei es aber zu einem Überlauf kommt, wenn die Summe aus Vorkomma- und Nachkommastellen 31 übersteigt.

Bei Verwendung gepackter Zahlen sollte immer die Programmeigenschaft Festpunktarithmetik gesetzt sein, da nur dann kommagerecht gerechnet wird. Ansonsten werden alle Zahlen als ganze Zahlen aufgefasst und auch alle Zwischenergebnisse zur nächsten ganzen Zahl gerundet. Ohne Setzen von Festpunktarithmetik werden die Nachkommastellen der Zahl nur bei der Ausgabe auf Dynpros oder bei der Aufbereitung mit WRITE [TO] berücksichtigt.

Rechenoperationen unter Rechentyp p werden mit Festpunktarithmetik durchgeführt. D.h. eine Berechnung wird "kaufmännisch" durchgeführt, wie man es vom Taschenrechner oder vom Rechnen mit Papier und Bleistift gewohnt ist. Typische Anwendungsbeispiele für Typ p sind Größen wie Längen, Gewichte und Geldbeträge.

Hinweis

Die Anzahl der Nachkommastellen einer gepackten Zahl sollte nicht größer als die Anzahl der Ziffern sein, da das Dezimaltrennzeichen ansonsten außerhalb der Ziffernfolge liegt. Eine gepackte Zahl, die mehr Nachkommastellen als Stellen hat, kann bei der Konvertierung in externe Formate wie Datentypen der Datenbank in Open SQL oder bei der Serialisierung nach asXML zu Ausnahmen führen.

Beispiel

Typische Verwendung des Datentyps p.

DATA price TYPE p LENGTH 16 DECIMALS 2.

Gleitpunktzahlen

Bei einer Gleitpunktzahl ist die Anzahl der Nachkommastellen Teil des Werts und nicht des Datentyps.

Dezimale Gleitpunktzahlen

Die Datentypen für dezimale Gleitpunktzahlen sind decfloat16 und decfloat34. Der Wertebereich ist 1E385(1E-16 - 1) bis -1E-383, 0, +1E-383 bis 1E385(1 - 1E-16) für decfloat16 und 1E6145(1E-34 - 1) bis -1E-6143, 0, +1E-6143 bis 1E6145(1 - 1E-34) für decfloat34. Die maximale Genauigkeit ist 16 Stellen bzw. 34 Stellen. Neben ihrem Wert hat eine dezimale Gleitpunktzahl noch eine Skalierung und eine Präzision. Diese Eigenschaften spielen bei Berechnungen und Vergleichen von Werten keine Rolle, gehen aber in Konvertierungsregeln und in Aufbereitungen von Ausgaben ein.

Dezimale Gleitpunktzahlen mit Nachkommastellen oder Exponenten können im Programm nicht direkt angegeben werden. Statt dessen muss man Zeichenliterale verwenden, deren Inhalt als Zahl interpretiert werden kann, d.h. eine Zahl in mathematischer, wissenschaftlicher oder kaufmännischer Notation darstellt.

Arithmetische Ausdrücke mit dezimalen Gleitpunktzahlen haben immer den Rechentyp decfloat34. Jede Berechnung wird mit dezimaler Gleitpunktarithmetik durchgeführt. Wenn es auf Präzision und einen großen Wertebereich ankommt, sind Berechnungen mit dezimalen Gleitpunktzahlen das Mittel der Wahl. Sie haben nicht die unten geschilderten Nachteile binärer Gleitpunktzahlen, die nicht jede Dezimalzahl innerhalb ihres Wertebereichs exakt darstellen können, und sie haben einen viel größeren Wertebereich und eine höhere Präzision als gepackte Zahlen.

Mit dem Lossless-Operator EXACT kann unter bestimmten Voraussetzungen für dezimale Gleitpunktzahlen sogar eine verlustfreie Berechnung erzwungen werden. In einer verlustfreien Berechnung sind keine Rundungen erlaubt und führen zu einer Ausnahme.

Intern werden dezimale Gleitpunktzahlen durch eine 16- bzw. 34-stellige dezimale Mantisse und einen dezimalen Exponenten dargestellt werden, der zwischen -383 und +384 bzw. -6143 und + 6144 liegt. Bis auf eventuelle Rundungen bei Zuweisungen und Berechnungen kommt es nicht zu den unten für binäre Gleitpunktzahlen geschilderten Effekten, da jede 16- bzw. 34-stellige Dezimalzahl exakt dargestellt werden kann.

Binäre Gleitpunktzahlen

Der Datentyp für binäre Gleitpunktzahlen f hat einen Wertebereich von 2,2250738585072014E-308 bis 1,7976931348623157E+308, und zwar positiv und negativ, sowie die Zahl 0; die Genauigkeit entspricht gut 15 Stellen. In ABAP dargestellt werden 17 Stellen. Ganze Zahlen können bis zu einem Absolutwert von 2**53 entsprechend 9.007.199.254.740.992 exakt dargestellt werden. Größere Zahlen werden gerundet.

Binäre Gleitpunktzahlen können im Programm nicht direkt angegeben werden. Statt dessen muss man Zeichenliterale verwenden, deren Inhalt als Gleitpunktzahl interpretiert werden kann, d.h. eine Zahl in wissenschaftlicher Notation darstellt. Die mathematische oder kaufmännische Notation sind nicht zulässig, es sei denn, sie sind als wissenschaftliche Notation interpretierbar.

Arithmetische Ausdrücke mit Rechentyp f werden mit binärer Gleitpunktarithmetik durchgeführt. Dabei muss man jedoch die im folgenden beschriebenen Effekte berücksichtigen.

Intern werden binäre Gleitpunktzahlen durch einen Dualbruch und einen Dualexponenten dargestellt. Dadurch kann es trotz der eigentlich hohen Genauigkeit zu überraschenden Effekten kommen. Diese treten hauptsächlich bei Konvertierungen von und nach Typ f auf.

Immerhin rundet die ABAP-Laufzeitumgebung kaufmännisch und nicht numerisch wie die zugrunde liegende Maschinenarithmetik. Gemäß deren Rundungsalgorithmus müsste nämlich bei Endziffer 5 zur nächsten geraden Ziffer (statt zur nächstgrößeren Ziffer) gerundet werden, also 2,5 nach 2 und 3,5 nach 4.

Man sollte auch berücksichtigen, dass die Multiplikation mit einer (positiven oder negativen) Zehnerpotenz i.a. keine exakte Operation darstellt.

Neben Rundungsfehlern kommt es wegen der beschränkten Stellenzahl der Mantisse zu Auslöschungseffekten.

Man kann sich also bei binärer Gleitpunktarithmetik nicht auf die letzten Stellen verlassen. Insbesondere ist es meistens sinnlos, zwei binäre Gleitpunktzahlen a und b auf Gleichheit zu testen; stattdessen sollte man testen, ob der relative Abstand abs((a - b)/a) kleiner als eine vorgegebene Schranke, z.B. 10**(-7), ist.

Schließlich kann auch noch die Darstellung und damit der Wert einer auf der Datenbank gespeicherten binären Gleitpunktzahl plattformabhängig sein.

Hinweis

Für die Zuweisung von numerischen Werten an Textfelder und Textstrings bieten sich statt einer Konvertierung oft auch die Anweisung WRITE ... TO oder eingebettete Ausdrücke in Zeichenketten-Templates mit den zugehörigen Formatierungsoptionen an.

Beispiel

Das Ergebnis der Berechnung in result1 ist 0,81499999999999995 während es in result2 den erwarteten Wert 0,815 hat.

DATA: result1 TYPE f,
      result2 TYPE decfloat34.

result1 = 815 / 1000.
result2 = 815 / 1000.

cl_demo_output=>display( |Binary  floating point: { result1 }\n| &&
                         |Decimal floating point: { result2 }\n| ).

Ausführbares Beispiel

Gleitpunktzahlen, arithmetische Berechnungen