Rubrik: Variablen/Strings | VB-Versionen: VB.NET | 02.05.07 |
Der Datentyp DECIMAL in VB 2005 Hinweise zum Verhalten des Datentyps DECIMAL in VB 2005 | ||
Autor: Manfred Bohn | Bewertung: | Views: 12.642 |
ohne Homepage | System: WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | kein Beispielprojekt |
Die Dokumentation zu VB 2005 gibt u.a. folgende Erläuterungen zum Datentyp DECIMAL:
Eine DECIMAL-Zahl ist ein Gleitkommawert, der aus einem Vorzeichen, einem numerischen Wert mit Ziffern zwischen 0 (null) und 9 sowie einem Skalierungsfaktor besteht, der die Position eines die Vor- und Nachkommastellen des numerischen Werts trennenden Gleitdezimaltrennzeichens angibt. Die binäre Darstellung besteht aus einem 1-Bit-Vorzeichen, einer 96-Bit-Ganzzahl und einem Skalierungsfaktor, der zum Dividieren der 96-Bit-Ganzzahl verwendet wird und angibt, welcher Teil ein Dezimalbruch ist. Der Skalierungsfaktor ist implizit die Zahl 10 mit einem Exponent zwischen 0 und 28.
Der DECIMAL-Werttyp ist für finanzmathematische Berechnungen geeignet, bei denen zahlreiche signifikante Vor- und Nachkommastellen erforderlich sind und keine Rundungsfehler auftreten dürfen. Dieser Typ stellt Methoden bereit, die zwischen DECIMAL-Werten und Single sowie Double konvertieren. Konvertierungen in Single oder Double sind einschränkende Konvertierungen, bei denen zwar ein Verlust an Genauigkeit, jedoch kein Verlust an Informationen über die Größe des konvertierten Werts auftreten kann. Die Konvertierung löst keine Ausnahme aus.
Damit wird ein erstes Problem - allerdings nur unzureichend - benannt. Bei direkter Zuweisung eines Decimal-Wertes auf einen IEEE-Gleitkomma-Datentyp tritt zumeist ein Verlust gültiger Stellen ein, aber selbst bei Verwendung von 'OPTION STRICT ON' weist die VB-Entwicklungsumgebung darauf nicht hin. Die VB-Dokumentation listet diese Umwandlung deshalb auch als sog. Erweiterungskonvertierung auf. (Die direkte Zuweisung eines DOUBLE auf einen DECIMAL wird im Gegensatz dazu STRICT "abgemahnt", vermutlich weil DECIMAL nur über eine eingeschränkte Werte-Spannweite verfügt.)
Große Einschränkungen gibt es bei der Durchführung mathematischer Berechnungen mit dem Datentyp DECIMAL. Die Funktionen in der VB-Klasse MATH sind zumeist nicht für den Datentyp DECIMAL ausgelegt. Dies trifft auf die Winkelfunktionen, Potenzen und Wurzeln (POW, SQRT), Logarithmen (LOG, EXP) und die Sonderzahlen (E, PI) zu.
Nur einfache DECIMAL-Manipulationen sind mit dieser Klasse möglich: ABS, SIGN, CEILING, FLOOR, TRUNCATE, ROUND, MAX, MIN.
Bei Verwendung von 'OPTION STRICT ON' verlangt die Entwicklungsumgebung die Verwendung der expliziten Konvertierungsfunktion 'CDBL' bei Übergabe eines DECIMAL-Wertes an eine nicht für DECIMAL überladene mathematische Funktion.
Der für VB6 geschriebenen VBARCHIV-Tipps zum Datentyp DECIMAL enthalten deshalb einige mathematische Funktionen, die dessen hohe Genauigkeit besser ausschöpfen.
Obwohl die VB-Dokumentation den Datentyp DECIMAL wegen seiner Genauigkeit für finanzmathematische Berechnungen empfiehlt, sind die entsprechenden VB-Funktionen im Modul 'FINANCIAL' (Namespace: Microsoft.VisualBasic) nicht für diesen Datentyp überladen (DDB, FV, IRR, NPV, PMT usw.) Sie verarbeiten bei Berechnung von Abschreibungen, Zinsen, Barwerten oder Auszahlungen den Datentyp DOUBLE.
In VB 2005 ist der Währungs-Datentyp 'CURRENCY' nicht mehr enthalten. Variablen vom Datentyp Currency wurden (bis VB6) als 64-Bit-Zahlen in einem ganzzahligen Format gespeichert und durch 10.000 dividiert, was eine Festkommazahl mit 15 Vorkomma- und 4 Nachkommastellen ergab. Dieser Datentyp eignete sich besonders für Berechnungen mit Geldbeträgen und für Festkomma-Berechnungen, die eine hohe Genauigkeit erfordern.
Die VB-2005-Dokumentation meldet dazu lakonisch: Der Currency-Datentyp wird nicht unterstützt. Verwenden Sie stattdessen den neuen Decimal-Datentyp, der bei allen Währungsvariablen und -berechnungen mehr Stellen auf beiden Seiten des Dezimalkommas verarbeiten kann. Decimal wird auch von der Common Language Runtime direkt unterstützt.
Bei der Umstellung von älteren VB-Programmen ist zu beachten, dass DECIMAL ein Gleitkomma-Verhalten aufweist, während CURRENCY über eine feste Zahl von vier Nachkommastellen verfügte. Im Einzelfall treten deshalb bei DECIMAL-Berechnungen erheblich höhere Genauigkeiten auf als bei CURRENCY-Berechnungen. Will man das vermeiden, sind die Ergebnisse von DECIMAL-Berechnungen zusätzlich explizit auf vier Stellen zu runden. (Die DECIMAL-Genauigkeit kann das Laufzeitverhalten von Algorithmen nach Umstellung der CURRENCY-Variablen erheblich verändern.)
Die integrierte DECIMAL-Methode 'ToOACurrency' wandelt eine Decimal-Zahl - falls möglich - in einen LONG-Wert um, wobei jedoch das Komma in der Ziffernfolge weggelassen wird. Dies dient nur der Parameter-Übergabe im Rahmen der OLE-Automatisierung, eignet sich aber nicht für Berechnungen.
Der Datentyp DECIMAL enthält die Grundrechnungsarten, Rundungsverfahren, Konvertierungen und Inkrement/Dekrement als explizit verwendbare öffentliche Methoden. Auch die Zuweisung des Ergebnisses einer DECIMAL-Rechenmethode auf eine DOUBLE-Variable wird von der IEE - OPTION STRICT ON - nicht moniert: DBL = DECIMAL.ADD(DEC1, DEC2)
Da die Operatoren der Grundrechenarten für den Datentyp DECIMAL überladen sind, ist die Verwendung der integrierten Methoden ADD, SUBTRACT, MULTIPLY, DIVIDE nicht erforderlich. Die Rechen-Genauigkeit leidet nicht darunter. Anders sieht es beim Potenz-Operator aus. Der ist nicht für DECIMAL überladen und es gibt auch keine integrierte DECIMAL-Methode. Von Interesse kann manchmal die integrierte Methode REMAINDER sein, die den Divisionsrest zurückgibt. Die Methode 'GetBits' liefert lediglich ein vierelementiges Integerarray, dessen erste drei Felder die Bitfolge des Decimal-Wertes enthalten und das vierte Feld im oberen Byte zunächst den Skalierungs-Exponenten und danach die Vorzeichenkennung repräsentiert. Will man das Bitmuster des Wertes (z.B. als String) erhalten, sind deshalb weitere Konvertierungen erforderlich.
Anders als die IEEE-angepassten Gleitkomma-Datentypen (DOUBLE, SINGLE) wird bei DECIMAL-Variablen eine Ausnahme ausgelöst, falls ein arithmetischer Überlauf oder eine Division durch 0 auftritt. Das ist immer dann von Interesse, wenn man bei komplexeren Berechnungen vermeiden will, dauernd die Zwischenergebnisse explizit auf etwaige Überläufe untersuchen zu müssen, um Fehlberechnungen aufgrund der Verarbeitung von zurückerhaltenen IEEE-Sonderwerten zu vermeiden.
Die IEEE-Sonderwerte 'Infinity' oder 'NAN' können deshalb auch nicht auf eine Variable des Typs DECIMAL zugewiesen werden. Der Versuch löst eine Overflow-Ausnahme aus.
Der Rechenzeit-Bedarf steigt bei Verwendung des Datentyps DECIMAL drastisch an. Im Einzelfall tritt, bei Durchführung von umfangreicheren Anwendungen der Grundrechenarten, bereits der Zeit-Faktor hundert auf - im Vergleich zum Bedarf bei Verwendung des Datentyps DOUBLE.