Dieser Workshop zeigt Details zum DECIMAL-Datentyp Format auf erläutert Unterschiede zwischen dem IEEE-Format und dem DECIMAL-Format. Weiterhin wird auf den Dateizugriff bei numerischen VARIANT-Variablen eingegangen, sowie ein Klassenmodul zur Arrayverwaltung vorgestellt. Der Untertyp DECIMAL des allgemeinen VB-Datentyps VARIANT bietet genaue Ganzzahl- und Gleitkomma-Berechnungen durch 96-Bit-Zahlen. Dieser Workshop informiert über
1. Das allgemeine IEEE-Gleitkomma-Format und das VB-spezifische Format DECIMAL Die VB-Gleitkomma-Datentypen SINGLE bzw. DOUBLE speichern Werte imIEEE-Format. Das IEEE-Format (IEEE steht dabei für "Institute of Electrical and ElectronicsEngineers") ist eine allgemein definierte Gleitkommadarstellung für digitale Systeme. MICROSOFT begründet die Verwendung dieses Formats in Visual Basic hinsichtlich der Kompatibilität mit den Programmiersprachen FORTRAN und C und weil es sich dabei um einen weltweit anerkannten"Industrie-Standard" handelt. (Quick-Basic hatte ursprünglich (Version 3) ein MS-spezifisches Gleitkomma-Format mit zwar geringerer Spannweite aber dafür höherer Genauigkeit). In IEEE wird für Variablen des Typs DOUBLE eine Gesamtlänge von 64 Bit festgelegt (davon 1 Bit Vorzeichen, 11 Bits Exponent, 52 BitsMantisse). Durch die Zerlegung von Gleitkommazahlen in Mantisse und Exponent erreicht man, dass ein größerer Zahlenbereich in beschränkterem Speicherplatz untergebracht werden kann, als es bei Festkommazahlen (wie z.B. Currency) der Fall ist. Eine Gleitkomma-Zahl wird dabei dargestellt als s * Mantisse * 2^Exponent (wobei s im Intervall -1 bis 1 liegt). Die üblichen PC-Prozessoren und ihre mathematischen Koprozessoren erlauben die besonders effiziente Verarbeitung desIEEE-Formats. Dieses Format besitzt einige charakteristische Eigenschaften: Die Abbildung eines als stetig angenommenen Zahlenbereichs auf eine begrenzte Menge von Binärzuständen erzwingt Rundungs-Ungenauigkeiten. Dieser Rundungsfehler kann berechnet werden. Bei DOUBLE-Variablen beträgt die Rundungs-Ungenauigkeit 2^(-52) d.h. ca. 2.2 * 10^(-16). Diese Abweichung fließt in Gleitkommaberechnungen ein. Der Rundungsmechanismus in Visual Basic entspricht dem IEEE-Standard (Suche nach dem"nähesten Nachbarn"). Zur Verdeutlichung der Problematik einige zusammenfassende Anmerkungen nach einem Artikel, der in der MSDN enthalten ist: Nur Zahlen, die in der Form p/(2^q) darstellbar sind, können durch eine begrenzte Zahl von Bits korrekt abgebildet werden. Sogar eine einfache Dezimalzahl wie 0.0001 benötigt für eine exakte IEEE-Darstellung eine sich wiederholende Periode von 104 Bits. Es sind u.a. folgende Fehler-Arten zu unterscheiden:
Durch die unterschiedliche binäre und dezimale Darstellung der Zahlen kann es dazu kommen, dass Zahlen die unmittelbar "rund" erscheinen, alsoz. B. als 15.35 ausgegeben werden, in Wirklichkeit bei der Berechnung einen auf Bitebene dargestellten Wert von 15.3499999993278 erhalten (fiktives Beispiel). Zahlen im Gleitkommaformat (DOUBLE / SINGLE) sollte man deshalb nie auf Gleichheit prüfen [a=b], sondern stets die Größe der absoluten Differenz abfragen [ABS(a-b) < Epsilon]. Die erforderliche Ausprägung des Epsilon-Wertes ist von der Absolutausprägung der verglichenen Zahlen abhängig. Die Ergebnisse im folgenden Beispiel hat ein INTEL-CELERON-Prozessor geliefert: Dim ax as Double, bx as Double bx = 0.12345678901234 ax = (bx ^ 2.5) ^ (1 / 2.5) Die berechnete Variable ax wird (scheinbar korrekt) ausgegeben als: 0.12345678901234 Näheren Aufschluss liefert die Betrachtung der 64-er Bitmuster, die die beiden Variablen enthalten: bx = 12345678901234# ax = (bx ^ 2.5) ^ (1 / 2.5) Die Variable ax wird (scheinbar korrekt) ausgegeben als: 12345678901234 Auch hier wieder ein Blick auf die 64er-Bitmuster: Die Prüfung der "Gleichheit" von zwei Double-Variablen ist nicht so einfach, wie es oft dargestellt wird. Wählt man beim Vergleich großer Zahlen einen zu kleinen Wert für die Epsilon-Konstante, werden die beiden Zahlen nie als gleich erkannt. Die Routine "IsEqual" weist den Weg, wie man den Vergleich über die Berechnung eines relativen Epsilon-Wertes durchführen kann. (Da sich bei komplizierten Berechnungen mit vielen Wert-Zuweisungen die Rundungs-Ungenauigkeiten potenzieren können, muss die Epsilon-Konstante eventuell vergrößert werden.) Der Vergleich CDec(ax) - CDec(bx) liefert in beiden Fällen die (dezimal korrekte) Differenz 0. Bei der Umwandlung eines Double-Wertes in einen Decimal-Wert durch CDEC wird also nicht auf die interne Bit-Darstellung des Double-Wertes zugegriffen, wie sie bei Berechnungen verwendet wird, sondern auf dessen Dezimal-Darstellung. Die Verwendung der Funktion CDEC bietet dennoch KEINEN eleganten Ausweg, um die Gleichheit von zwei Double-Werten zu prüfen. Ungenauigkeiten können nämlich so groß werden, dass"eigentlich" identische Werte auch dezimal unterschiedlich dargestellt sind. Man kann der"Epsilontik" im IEEE-Fomat nicht entkommen. ' ============================================================================= ' Beginn QuellCode von IsEqual ' ============================================================================= Function IsEqual(ByVal a As Double, ByVal b As Double, _ Optional ByRef Differenz As Double, _ Optional ByRef RelativeDifferenz As Double) As Boolean ' Die Funktion prüft, ob zwei Double-Werte als "gleich" betrachtet ' werden können ' In den optionalen Parametern wird der Betrag der absoluten ' und der relativen Differenz zurückgegeben ' absolute Epsilon-Konstante Const epsilon As Double = 0.000000000001 ' Hilfs-Konstante Const zwei As Double = 2# ' relatives Epsilon Dim rel_eps As Double Dim Mittel As Double On Error GoTo fehler ' Rückgabe initialisieren Differenz = 0: RelativeDifferenz = 0 ' Betrag der Differenz der beiden Werte ' Falls es hier zum Überlauf kommt, liegt mit ' Sicherheit ein Unterschied vor (Rückgabe: false)! Differenz = Abs(a - b) ' Bestimmung des geeigneten Epsilon-Wertes ' (Überlauf und Division durch Null verhindern!) Mittel = Abs(a / zwei + b / zwei) If Mittel < epsilon Then Mittel = epsilon Else ' Relative Differenz der beiden Werte ' bezogen auf deren arithmetisches Mittel RelativeDifferenz = Differenz / Mittel End If rel_eps = epsilon * Mittel ' Differenz-Betrag kleiner Vergleichs-Epsilon ? IsEqual = (Differenz < rel_eps) fehler: End Function ' ============================================================================= ' Ende QuellCode von IsEqual ' ============================================================================= Im Gegensatz zu DOUBLE / SINGLE greift der VARIANT-Untertyp DECIMAL nicht auf ein exponentbehaftetes Gleitkomma-Verfahren zurück, sondern wird intern als vorzeichenlose, positive 96-Bit-Ganzzahl gespeichert. Die Anzahl der Nachkommastellen und das Vorzeichen werden als Zusatzinformation gespeichert. Aufbau einer 16 Byte langen Variable vom Typ VARIANT / Untertyp DECIMAL: 1. Byte: Kennung für Decimal (14) 2. Byte: unbelegt (0) 3. Byte: Anzahl der Nachkommastellen (0-28) 4. Byte: Vorzeichen (0=positiv; 128=negativ) 5-16. Byte: vorzeichenlose Ganzzahl (96-Bit-Muster) Die Abfolge der Verwendung der Byte-Positionen für die Speicherung der 96-Bit-Ganzzahl beim Hochzählen von 0 ist anders, als man es erwarten würde: 9-10-11-12-13-14-15-16-5-6-7-8 Variablen des Datentyps DECIMAL bieten eine eindeutige Zuordnung zwischen dezimaler und binärer Darstellung. Dabei ergibt sich der Nachteil, dass der darstellbare Zahlenbereich beschränkt ist. Falls die Ergebnisse von Rechen-Operationen sich durch maximal 28 Stellen vollständig darstellen lassen (alsoz. B. keine periodischen Brüche auftreten und keine Kommastellen abgeschnitten werden), sind sie auf der Basis von Variablen des Typs DECIMAL exakt, weil keine Rundungen erforderlich werden. Wiederholung des obigen Beispiels für Decimals: Dim ax As Variant, bx As Variant bx = CDec(0.12345678901234) ax = CDec((bx ^ CDec(2.5)) ^ (CDec(1) / CDec(2.5))) Die 96er-Bitmuster (Byte 5-16) der beiden Variablenwerte sind identisch: bx = CDec(12345678901234#) ax = CDec((bx ^ CDec(2.5)) ^ (CDec(1) / CDec(2.5))) Auch hier sind die 96er-Bitmuster (Byte 5-16) identisch: Wer genau hinschaut wird feststellen, dass beide Bitmuster identisch sind. Das liegt daran, dass dieser Datentyp eine vorzeichenlose Ganzzahl enthält. Der Unterschied zwischen den Zahlen in beiden Beispielen wird erst erkennbar, wenn man auch die vier Verwaltungsbytes der Variant-Variable mit einbezieht. Das dritte Byte definiert die unterschiedlichen Nachkommastellen. Verwaltungsbits im ersten Beispiel = 01110000 | 00000000 | 01110000 | 00000000 Die Verwaltung des Datentyps DECIMAL als VARIANT-Variable erfordert eine Speicherung von 16 Byte. Die Verwendung von Arrays des Datentyps VARIANT belegt mehr Speicher als notwendig, weil 13 Byte (12 Byte + 1 Byte für Vorzeichen und Nachkommastellen) ausreichen, um alle benötigten Informationen aufzunehmen. (Das Verwaltungsbyte wird dabei mit der Summe der Bytes 3/4 der VARIANT-Variablen belegt.) Die beigefügte Klasse "clsDecimal" kapselt ein Bytearray, das Arrayfelder des Typs DECIMAL speichersparend in jeweils 13 Bytes ablegt. Durch Verwendung der API-Funktion"RtlMoveMemory" bei der Zuweisung der Datenfelder wird dafür kaum zusätzliche Rechenzeit benötigt. 2. Ganzzahlen im IEEE-Format (DOUBLE) und im DECIMAL-Format Visual Basic bietet für die Verarbeitung von Ganzzahlen die Datentypen INTEGER und LONG. Der Nachteil beim 16- bzw. 32-Bit-Format ist die relativ geringe zulässige Spannweite der Werte. Bei LONG-Variablen beträgt sie +/-2147483647 (=2^31-1). Für größere Ausprägungen werden meist Variablen des Datentyps DOUBLE eingesetzt. Die 51-Bit-Mantisse dieses Formats ermöglicht deutlich größere Ganzzahlen im Bereich +/-999999999999999 (= -1E15+1 bis 1E15-1). Allerdings ist Vorsicht geboten. Da es sich um ein Gleitkomma-Format handelt, muss man bei Wertzuweisungen darauf achten, dass intern keine automatische Umstellung auf (gerundete) Exponentialdarstellung erfolgt. Auch in der Dezimaldarstellung ganzzahlig erscheinende Daten können intern gerundet sein, so dassz. B. die Abfrage auf "Gleichheit" scheitert. Die Typumwandlungsfunktionen CINT bzw. CLNG sind nur bei Werten im Geltungsbereich INTEGER bzw. LONG verwendbar. Man ist deshalb auf die Funktionen ROUND bzw. INT angewiesen. Sie sollten bei jeder Wertzuweisung (Berechnungs-Ergebnis) auf eine als Ganzzahl verwendete DOUBLE-Variable eingesetzt werden - und zwar am besten bereits BEI der Zuweisung (nicht danach). Zusätzlich muss darauf geachtet werden, dass kein "impliziter Ganzzahl-Überlauf" stattfindet, weil sonst automatisch zur Exponentialdarstellung gewechselt wird - die Variable enthält dann keine Ganzzahl mehr. Die ROUND-Funktion verwendet ein "ungewöhnliches" Rundungsverfahren, das insbesondere bei der Umwandlung von Gleitkommazahlen in Ganzzahlen unerwartete Effekte zeigen kann. (Dieses - in der Mathematik gebräuchliche Verfahren - sorgt dafür, dass die letzte beibehaltene Ziffer stets gerade ist, falls die erste verworfene Ziffer 5 ist.) Die Datenreihe
wird von der VB-Funktion ROUND in folgende Ganzzahlen umgesetzt:
Dieses Umwandlungs-Ergebnis ist vermutlich in den meisten Fällen nicht erwünscht. Besser ist es, man schreibt eine eigene Funktion, die bei .5 immer einheitlich auf- oder abrundet (die INT-Funktion ermittelt dabei den ungerundeten Vorkomma-Anteil). Als weitere Alternative ist ein Rundungsprinzip denkbar, das bei positiven Zahlen ab 0.5 auf- und bei negativen Zahlen ab 0.5 abrundet. Die Wahl des Rundungsverfahrens kann einen erheblichen Einfluss auf das erzielte Ergebnis haben. Die Routine GANZZAHL sorgt dafür, dass in einer Double-Variable tatsächlich ein ganzzahliger Wert enthalten ist (und löst bei Ganzzahl-Überlauf einen Fehler aus). Sie wandelt die obige Datenreihe in
um. ' ========================================================================== ' Start Quellcode Routine GANZZAHL ' ========================================================================== Function Ganzzahl(ByVal wert As Double) As Double ' Die Funktion wandelt einen DOUBLE-Wert in eine ' Ganzzahl um (Rundung) Dim iwert As Double ' maximal mögliche Ganzzahl in DOUBLE - 1 (wg. Rundung) Const MaxInteger As Double = (1E+15 - 2) iwert = Abs(wert) If iwert > MaxInteger Then ' impliziter Ganzzahl-Überlauf Err.Raise 6 Exit Function End If ' Rundung auf Ganzzahl iwert = Int(wert) ' INT liefert stets kleinere Ganzzahl If wert - iwert >= CDbl(0.5) Then ' ab .5 immer aufrunden wert = iwert + 1 Else ' sonst abrunden wert = iwert End If Ganzzahl = wert End Function ' ========================================================================== ' Ende Quellcode Routine GANZZAHL ' ========================================================================== Der VB-Datentyp CURRENCY verarbeitet 64-Bit als Festkomma-Zahl mit vier Nachkommastellen. Der Datentyp DECIMAL bietet eine noch erheblich größere Spannweite für die Ausprägung von Ganzzahlen als DOUBLE-Variable. In den 96-Bit dieses Datenformats können Werte im Bereich +/-79.228.162.514.264.337.593.543.950.335 enthalten sein (ca. 2^96 - 2^43). ' ========================================================================== ' Start Quellcode Routine GANZZAHL_DEC ' ========================================================================== Function Ganzzahl_Dec(ByVal wert As Variant) As Variant ' Die Funktion wandelt einen numerischen Wert in eine ' Ganzzahl um (Rundung): Rückgabe DECIMAL Dim iwert As Variant ' maximal mögliche Ganzzahl in DECIMAL - 1 (wg. Rundung) Dim MaxInteger As Variant MaxInteger = CDec("79228162514264337593543950334") If Not IsNumeric(wert) Then ' Typenkennungs-Alarm Err.Raise 13 Exit Function End If iwert = Abs(wert) If iwert > MaxInteger Then ' Überlauf Decimal Err.Raise 6 End If ' Untertyp sicherstellen If VarType(wert) <> vbDecimal Then wert = CDec(wert) End If ' Rundung auf Ganzzahl iwert = Int(wert) ' INT liefert stets kleinere Ganzzahl If wert - iwert >= CDec(0.5) Then ' ab .5 immer aufrunden wert = iwert + CDec(1) Else ' sonst abrunden wert = iwert End If Ganzzahl_Dec = wert End Function ' ========================================================================== ' Ende Quellcode Routine GANZZAHL ' ========================================================================== Um einen Eindruck von den mit den Datentypen zu erreichenden Spannweiten zu bekommen: LONG-Variablen können die Fakultät 12 darstellen, DOUBLE-Variablen die Fakultät 17 (als Ganzzahl !) und DECIMAL-Variablen die Fakultät 27. Vielleicht stellt sich jetzt noch die Frage, wie die Zahlenwerte mit den vielen Nullen benannt sind (in Klammern: die abweichende Bezeichnungsweise im US-System):
3. Das Verhalten des Datentyps DECIMAL beim Dateizugriff Der sequentielle Dateizugriff durch WRITE / INPUT und der binäre bzw. wahlfreie Dateizugriff durch PUT / GET unterstützen auch den Datentyp DECIMAL. Sequentieller Zugriff: Wenn mit Write# Daten des Typs Variant/numerischer Untertyp sequentiell in eine Datei geschrieben werden, gelten einige Besonderheiten, damit diese Daten - unabhängig vom Gebietsschema - mit Input# wieder korrekt eingelesen und auf Variable zugewiesen werden können:Numerische Daten werden immer mit dem Punkt als Dezimaltrennzeichen geschrieben. Wenn Daten in der Ausgabeliste den Wert "Empty" haben, werden keine Daten in die Datei geschrieben. Für den Wert Null wird #NULL# in die Datei geschrieben. Bei der sequentiellen Ausgabe mit WRITE# werden die DECIMAL-Daten unformatiert ausgegeben. Dabei werden jeweils nur so viele Ziffern ausgegeben, wie nötig (keine führenden oder angehängten Nullen). Die Zahlen in der Ausgabedatei können deshalb sehr unübersichtlich angeordnetsein. Bei Zahlen, die mit INPUT# wieder gelesen werden sollen, wird eine formatierte Ausgabe durch PRINT# in der VB-Dokumentation nicht empfohlen. Will man dennoch Zahlen formatiert ausgeben, muss zuvor das Dezimaltrennzeichen ausgetauscht werden und - falls mehrere Zahlen in einer Zeile stehen - als Daten-Trennzeichen das Komma eingefügt werden. Beim sequentiellen Lesen mit INPUT# ist zu beachten, dass in Deutschland als Dezimaltrennzeichen in Datendateien oft ',' (Ascii-Code 44) und nicht der Dezimalpunkt '.' (Ascii-Code 46) verwendet wird. Vor dem Lesen aus solchen Dateien muss deshalb zunächst ein globales Ersetzen durchgeführt werden. Damit es dabei nicht zu Kollisionen mit dem Tausendertrennzeichen kommt, sollte zuvor ggf. noch der meist als Tausender-Trennzeichen verwendeteStandard-Dezimalpunkt aus der Datei entfernt werden. Die Klasse "clsDecimal" enthält die beiden Methoden WRITEARRAY undINPUTARRAY für das sequentielle Schreiben und Lesen des gekapselten Array-Inhaltes. WRITEARRAY formatiert die ausgegebenen Zahlen so, dass der Dezimalpunkt in der Datei bei allen Daten eine feste Position besitzt. Eine durchWRITEARRAY gefüllte Datei kann mit INPUTARRAY wieder korrekt gelesen werden. Bei überlangen Zahlenschlangen in einer sequentiellen Datei (>28 Ziffern) und bei Exponential-Zahlen über +/-1E28 löstINPUTARRAY die Ereignismeldung "Überlauf" aus. Nicht-Numerische Angaben in der Datei führen zur Ereignismeldung"Typen unverträglich". Beim ersten Auftreten eines Fehlers brichtINPUTARRAY den Lesevorgang ab und gibt "false" zurück. Exponentialzahlen werden beim Lesen in Dezimalzahlen umgewandelt (1.2E08 --> 120000000). Bei zu vielen Nachkommastellen wird gerundet (abhängig von der Zahl der Vorkommastellen). Leerzeilen in der Datei werden als cDec(0) ins Array eingetragen!! Binärer Zugriff: Der binäre Dateizugriff eignet sich besonders gut, um einen komplexen benutzerdefinierten Datentyp (UDT), der aus Strings, numerischen Typen, variablen Arrays und anderen UDTs zusammengesetzt sein kann, mit nur einer PUT-Anweisung in eine Datei zu schreiben, und mit nur einer GET-Anweisung alle Daten aus der Datei wieder einzulesen. Ein typischer Anwendungsfall ist das Speichern der Member-Variablen einer Klasse bzw. das Füllen einer neuen Objektinstanz mit diesen Daten aus einer Datei. Wenn die zu schreibende UDT-Variable ein dynamisches Datenfeld enthält, schreibt PUT# zunächst einen Array-Deskriptor, dessen Länge 2 plus 8 mal Anzahl der Array-Dimensionen beträgt. Abfolge der Bytes in der Datei nach dem Schreiben eines zweidimensionalen dynamischen Arrays (Redim-Deklaration) durchPUT# : Beim Schreiben einer UDT-Variable mit PUT# wird die Beachtung des folgenden Hinweises empfohlen: Beim Lesen der Variable die Arrays enthält mit GET#, erwartet diese Funktion an den korrekten Stellen die oben aufgelisteten Angaben zur korrekten Dimensionierung des Array. Verwendet man beim Lesen eine Datei, die nicht mit einer korrespondierenden PUT#-Anweisung binär geschrieben worden ist, kann es beim Lesen mit GET# zum Versuch der Dimensionierung riesiger Felder kommen. Das kann unabsehbare Effekte nach sich ziehen. Man schreibt deshalb mit PUT# zunächst einen eindeutigen Kennstring in die Datei, erst dann die Variable vom benutzerdefinierten Typ und zum Abschluss noch einmal den Kennstring. Beim Lesen mit GET# wird zunächst der Kennstring am Anfang und am Ende der Datei gelesen und geprüft. Falls durch diese Prüfung die Korrektheit der Datei gesichert ist, kann mit GET die Typvariable eingelesen werden. Die Klasse "clsDecimal" enthält die Methoden PUTARRAY / GETARRAY, die dieses Vorgehen demonstrieren. (Wer absolut sicher gehen will, keine inadäquaten Daten zu lesen, kann nach dem Schreiben der Datei zusätzlich eine Prüfsumme für den Dateiinhalt berechnen und -z. B. angehängt am Dateinamen - abspeichern. Vor dem Lesen einer solchen Datei wird zunächst die Prüfsumme kontrolliert und mit dem gespeicherten Wert verglichen.) Wahlfreier Zugriff: Beim wahlfreien Zugriff auf Datensätze einer Datei ist die korrekte Angabe der Datensatzlänge beim Öffnen der Datei zwingend notwendig. Ist die geschriebene Variable vom Typ VARIANT / numerischer Untertyp, so schreibt PUT zunächst 2 Bytes, die den Untertypkennzeichnen und dann den Inhalt der Variable. Bei einer VARIANT-Variablen des Typs 14 (DECIMAL) schreibt PUT 18 Bytes: 2 Bytes legen die VARIANT-Variable als DECIMAL fest, und 16 Bytes enthalten die Daten. Die im Len-Abschnitt der Open-Anweisung angegebene Datensatzlänge muss also mindestens 2 Bytes größer sein als die tatsächlich zum Speichern der Variablen benötigte Anzahl an Bytes. Wenn die Zielvariable ein dynamisches Datenfeld ist, schreibt PUT zuerst einen Deskriptor, dessen Länge 2 plus 8 mal der Anzahl der Dimensionen entspricht. Die durch den Len-Abschnitt der Open-Anweisung angegebene Datensatzlänge muss größer oder gleich der Summe aller Bytes sein, die erforderlich sind, um die Daten des Datenfeldes und den Datenfeld-Deskriptor zu schreiben. 4. Kurzbeschreibung der Eigenschaften und Methoden der Klasse "clsDecimal" Die Klasse "clsDecimal" kapselt ein eindimensionales Bytearray, dessen Felder Zahlen des Typs DECIMAL aufnehmen. Fehlerhafte Zugriffe oder interne Fehler lösen das Ereignis <FehlZugriff> aus, falls die Zugriffs-Variable der Klasse modulglobal mit dem Schlüsselwort WITHEVENTS deklariert worden ist. Intern werden die Daten in einem zweidimensionalen Byte-Array verwaltet (13 Byte / Feld). Es können nur Variablen vom Typ DECIMAL zugewiesen werden. Methode: DIMENSIONIEREN(Long, Long, [Boolean]) Inhalt des Demoprojekts
Die Klasse "clsDecimal" macht ausgiebig Gebrauch von der berüchtigten API-Funktion "RtlMoveMemory". Es ist deshalb eine Testprozedur erstellt worden, die 10000x eine Instanz der Klasse erstellt, zufällig dimensioniert, mit Zufalls-Werten gefüllt und dann die Methoden der Klasse ausgeführt hat. Diesen Test hat das Klassenmodul bestanden. Zur Dokumentation ist die verwendete Testroutine dem Zip-File beigefügt (frmDecimalCheck). Dieser Workshop wurde bereits 26.210 mal aufgerufen.
Anzeige
Diesen und auch alle anderen Workshops finden Sie auch auf unserer aktuellen vb@rchiv Vol.6 (einschl. Beispielprojekt!) Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
sevWizard für VB5/6 Professionelle Assistenten im Handumdrehen Erstellen Sie eigene Assistenten (Wizards) im Look & Feel von Windows 2000/XP - mit allem Komfort und zwar in Windeseile :-) Tipp des Monats Dezemeber 2024 Roland Wutzke MultiSort im ListView-Control Dieses Beispiel zeigt, wie sich verschiedene Sortierfunktionen für ein ListView Control realisieren lassen. TOP Entwickler-Paket TOP-Preis!! Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR... |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |