Problembehandlung bei Datentypen

Aktualisiert: Juli 2008

Auf dieser Seite sind einige Probleme aufgeführt, die häufig auftreten, wenn Operationen mit systeminternen Datentypen ausgeführt werden.

Gleitkommaausdrücke werden nicht als gleich ausgewertet

Wenn Sie mit Gleitkommazahlen (Single-Datentyp (Visual Basic) und Double-Datentyp (Visual Basic)) arbeiten, beachten Sie, dass sie als Binärbrüche gespeichert werden. Das bedeutet, dass sie keine präzise Darstellung einer Größe speichern können, die kein Binärbruch ist (ein Binärbruch ist eine Größe von der Form k / (2 ^ n)), wobei k und n ganze Zahlen sind). Beispielsweise können 0,5 (= 1/2) and 0,3125 (= 5/16) als präzise Werte gespeichert werden, während 0,2 (= 1/5) und 0,3 (= 3/10) nur annähernd genau gespeichert werden können.

Aufgrund dieser Ungenauigkeit können Sie keine genauen Ergebnissen erwarten, wenn Sie mit Gleitkommawerten arbeiten. Insbesondere können zwei Werte, die theoretisch gleich sind, geringfügig unterschiedliche Darstellungen aufweisen.

So vergleichen Sie Gleitkommagrößen

  1. Berechnen Sie den Absolutbetrag ihrer Differenz mit der Abs-Methode der Math-Klasse im System-Namespace.

  2. Legen Sie eine maximal zulässige Differenz fest, um die beiden Größen für praktische Zwecke als gleich zu betrachten, sofern ihre Abweichung nicht größer ist.

  3. Vergleichen Sie den absoluten Wert der Abweichung mit der zulässigen Abweichung.

Im folgenden Beispiel wird sowohl ein korrekter als auch ein fehlerhafter Vergleich zweier Double-Werte veranschaulicht.

Dim oneThird As Double = 1.0 / 3.0
Dim pointThrees As Double = 0.333333333333333

' The following comparison does not indicate equality.
Dim exactlyEqual As Boolean = (oneThird = pointThrees)

' The following comparison indicates equality.
Dim closeEnough As Double = 0.000000000000001
Dim absoluteDifference As Double = Math.Abs(oneThird - pointThrees)
Dim practicallyEqual As Boolean = (absoluteDifference < closeEnough)

MsgBox("1.0 / 3.0 is represented as " & oneThird.ToString("G17") _
  & vbCrLf & "0.333333333333333 is represented as " _
  & pointThrees.ToString("G17") _
  & vbCrLf & "Exact comparison generates " & CStr(exactlyEqual) _
  & vbCrLf & "Acceptable difference comparison generates " _
  & CStr(practicallyEqual))

Im vorhergehenden Beispiel wird die ToString-Methode der Double-Struktur verwendet. So wird eine größere Genauigkeit als mit dem CStr-Schlüsselwort erreicht. Der Standardwert ist 15 Stellen, aber mit dem Format "G17" wird er auf 17 Stellen erweitert.

Der Operator 'Mod' gibt kein präzises Ergebnis zurück

Aufgrund der Ungenauigkeit beim Speichern von Gleitkommazahlen kann der Operator Mod(Visual Basic) ein unerwartetes Ergebnis zurückgeben, wenn mindestens einer der Operanden eine Gleitkommazahl ist.

Der Decimal-Datentyp (Visual Basic) verwendet keine Gleitkommadarstellung. Viele Zahlen, die mit Single und Double ungenau sind, sind mit Decimal genau (z. B. 0,2 und 0,3). Obwohl die Berechnung mit Decimal langsamer als mit Gleitkommazahlen erfolgt, wiegt die größere Genauigkeit die geringere Leistung eventuell auf.

So ermitteln Sie den ganzzahligen Rest von Gleitkommagrößen

  1. Deklarieren Sie Variablen als Decimal.

  2. Verwenden Sie das Literaltypzeichen D, um Decimal für Literale zu erzwingen, für den Fall, dass sie für den Long-Datentyp zu groß sind.

Im folgenden Beispiel wird die potenzielle Ungenauigkeit von Gleitkommaoperanden veranschaulicht.

Dim two As Double = 2.0
Dim zeroPointTwo As Double = 0.2
Dim quotient As Double = two / zeroPointTwo
Dim doubleRemainder As Double = two Mod zeroPointTwo

MsgBox("2.0 is represented as " & two.ToString("G17") _
  & vbCrLf & "0.2 is represented as " & zeroPointTwo.ToString("G17") _
  & vbCrLf & "2.0 / 0.2 generates " & quotient.ToString("G17") _
  & vbCrLf & "2.0 Mod 0.2 generates " _
  & doubleRemainder.ToString("G17"))

Dim decimalRemainder As Decimal = 2D Mod 0.2D
MsgBox("2.0D Mod 0.2D generates " & CStr(decimalRemainder))

Im vorhergehenden Beispiel wird die ToString-Methode der Double-Struktur verwendet. So wird eine größere Genauigkeit als mit dem CStr-Schlüsselwort erreicht. Der Standardwert ist 15 Stellen, aber mit dem Format "G17" wird er auf 17 Stellen erweitert.

Weil zeroPointTwoDouble ist, ist sein Wert für 0,2 ein unendlicher Binärbruch mit dem gespeicherten Wert 0,20000000000000001. Die Division von 2,0 durch diese Größe ergibt 9,9999999999999995 mit dem Rest 0,19999999999999991.

Im zweiten Ausdruck für decimalRemainder erzwingt das Literaltypzeichen D, dass beide Operanden den Decimal-Datentyp aufweisen, und 0,2 wird präzise dargestellt. Darum liefert der Operator Mod den erwarteten Rest 0,0.

Beachten Sie, dass es nicht ausreicht, decimalRemainder als Decimal zu deklarieren. Sie müssen außerdem für die Literale Decimal erzwingen. Andernfalls ist ihr Standarddatentyp Double, und decimalRemainder erhält denselben ungenauen Wert wie doubleRemainder.

Boolescher Typ wird nicht präzise in den numerischen Typ konvertiert

Boolean-Datentyp (Visual Basic)-Werte werden nicht als Zahlen gespeichert, und die gespeicherten Werte sollen nicht mit Zahlen gleichwertig sein. Aus Gründen der Kompatibilität mit älteren Versionen stellt Visual Basic Konvertierungsschlüsselwörter (CType-Funktion, CBool, CInt usw.) zum Konvertieren zwischen Boolean-Typen und numerischen Typen bereit. In anderen Sprachen werden diese Konvertierungen jedoch zuweilen anders ausgeführt als mit den .NET Framework-Methoden.

Sie sollten nie Code schreiben, der von entsprechenden numerischen Werten für True und False abhängt. Beschränken Sie den Einsatz von Boolean-Variablen auf die logischen Werte, für die sie entworfen wurden. Wenn es erforderlich ist, Boolean-Werte und numerische Werte zu mischen, müssen Sie wissen, wie die gewählte Konvertierungsmethode arbeitet.

Konvertierung in Visual Basic

Wenn Sie mithilfe der Konvertierungsschlüsselwörter CType oder CBool numerische Datentypen in Boolean konvertieren, wird aus 0 False und aus alle anderen Werten True. Wenn Sie Boolean-Werte mit den Konvertierungsschlüsselwörtern in numerische Typen konvertieren, wird False zu 0 und True zu -1.

Konvertierung in .NET Framework

Die ToInt32-Methode der Convert-Klasse im System-Namespace konvertiert True in +1.

Achten Sie auf die verwendete Konvertierungsmethode, wenn Sie einen Boolean-Wert in einen numerischen Datentyp konvertieren.

Zeichenliteral generiert Compilerfehler

Sind keine Typzeichen angeben, verwendet Visual Basic für Literale Standarddatentypen. Der Standardtyp für ein Zeichenliteral – in Anführungszeichen (" ") – ist String.

Der String-Datentyp wird nicht zum Char-Datentyp (Visual Basic) erweitert. Wenn Sie einer Char-Variablen ein Literal zuweisen möchten, müssen Sie daher entweder eine Einschränkungskonvertierung ausführen oder den Char-Typ für das Literal erzwingen.

So erstellen Sie ein Zeichenliteral, um es einer Variablen oder Konstanten zuzuweisen

  1. Deklarieren Sie die Variable oder die Konstante als Char.

  2. Schließen Sie den Zeichenwert in Anführungszeichen (" ") ein.

  3. Fügen Sie nach dem schließenden doppelten Anführungszeichen das Literaltypzeichen C ein, um Char für das Literal zu erzwingen. Dies ist erforderlich, falls für die Typüberprüfung (Option Strict-Anweisung) On festgelegt ist, und empfiehlt sich auf jeden Fall.

Im folgenden Beispiel werden sowohl fehlgeschlagene als auch erfolgreiche Zuweisungen eines Literals zu einer Char-Variablen veranschaulicht.

Option Strict On
Dim charVar As Char
' The following statement attempts to convert a String literal to Char.
' Because Option Strict is On, it generates a compiler error.
charVar = "Z"
' The following statement succeeds because it specifies a Char literal.
charVar = "Z"c
' The following statement succeeds because it converts String to Char.
charVar = CChar("Z")

Die Verwendung von Einschränkungskonvertierungen ist immer mit Risiken verbunden, weil sie zur Laufzeit fehlschlagen können. Beispielsweise kann eine Konvertierung von String in Char fehlschlagen, wenn der String-Wert mehrere Zeichen enthält. In gut geschriebenen Programmen wird daher das C-Typzeichen verwendet.

Zeichenfolgenkonvertierung schlägt zur Laufzeit fehl

Der String-Datentyp (Visual Basic) wird in sehr wenigen Erweiterungskonvertierungen verwendet. String wird nur in sich selbst und zu Object erweitert, und nur Char und Char() (ein Char-Array) werden zu String erweitert. Der Grund hierfür ist, dass String-Variablen und -Konstanten Werte enthalten können, die andere Datentypen nicht behandeln können.

Wenn die Typüberprüfung (Option Strict-Anweisung) den Wert On hat, lässt der Compiler keine impliziten einschränkenden Konvertierungen zu. Das gilt auch für solche, die String betreffen. Im Code können dennoch Konvertierungsschlüsselwörter wie CStr und CType-Funktion verwendet werden, die .NET Framework anweisen, die Konvertierung auszuführen.

Hinweis:

Der Fehler für einschränkende Konvertierung wird unterdrückt für Konvertierungen von den Elementen in einer For Each…Next-Auflistung zur Schleifensteuerungsvariable. Weitere Informationen und Beispiele finden Sie im Abschnitt "Eingrenzende Konvertierungen" unter For Each...Next-Anweisung (Visual Basic).

Schutz von Einschränkungskonvertierungen

Einschränkungskonvertierungen weisen den Nachteil auf, dass sie zur Laufzeit fehlschlagen können. Wenn z. B. eine String-Variable einen anderen Wert als "True" oder "False" enthält, kann sie nicht in Boolean konvertiert werden. Wenn sie Satzzeichen enthält, schlägt die Konvertierung in jeden numerischen Typ fehl. Sofern Sie nicht sicher sind, dass eine String-Variable immer Werte enthält, die mit dem Zieltyp kompatibel sind, sollten Sie keine Konvertierung durchführen.

Wenn Sie String in einen anderen Datentyp konvertieren müssen, ist es am sichersten, die Konvertierung in eine Try...Catch...Finally-Anweisung (Visual Basic) einzuschließen. Dies ermöglicht die Behandlung eines Laufzeitfehlers.

Zeichenarrays

Sowohl ein einzelnes Zeichen vom Typ Char als auch ein Array von Char-Elementen wird zu String erweitert. String wird jedoch nicht zu Char() erweitert. Um einen String-Wert zu einem Char-Array zu erweitern, können Sie die ToCharArray-Methode der System.String-Klasse verwenden.

Bedeutungslose Werte

Im Allgemeinen sind String-Werte in anderen Datentypen ohne Bedeutung, und die Konvertierung ist von nur theoretischem Nutzen und sehr gefährlich. Beschränken Sie die Verwendung von String-Variablen nach Möglichkeit auf die Zeichenfolgen, für die sie entworfen wurden. Schreiben Sie niemals Code, der von entsprechenden Werten in anderen Datentypen abhängt.

Siehe auch

Konzepte

Datentypen in Visual Basic

Typzeichen

Typenloses Programmieren in Visual Basic

Datentypen sind .NET Framework-Typen

Effiziente Verwendung von Datentypen

Referenz

Datentyp: Zusammenfassung (Visual Basic)

Funktionen für die Typkonvertierung

Weitere Ressourcen

Datentypimplementierung

Typkonvertierung in Visual Basic

Änderungsprotokoll

Date

Versionsgeschichte

Grund

Juli 2008

Hinweis über einschränkende Konvertierungen und For Each…Next hinzugefügt.

Kundenfeedback.