Udostępnij za pośrednictwem


Rozwiązywanie problemów związanych z typami danych (Visual Basic)

Ta strona zawiera listę niektórych typowych problemów, które mogą wystąpić podczas wykonywania operacji na typy danych wewnętrznych.

Zmiennoprzecinkowe wyrażeń porównuje jako równe

Podczas pracy z liczb zmiennoprzecinkowych (Single — Typ danych (Visual Basic) i Double — Typ danych (Visual Basic)), należy pamiętać, są przechowywane jako ułamki binarny.Oznacza to, nie posiadają dokładną reprezentację wszelkie ilości, która nie jest binarny frakcji (formularza k / (2 ^ n) gdzie k i n są liczby całkowite).Na przykład 0,5 (= 1 i 2) i 0.3125 (= 5 i 16) można odbywać jako dokładne wartości (= 1 i 5) 0,2 i 0,3 (= 3 i 10) może być tylko przybliżeniem.

Z tego powodu niedokładności, użytkownik nie może polegać na dokładne wyniki gdy działają na wartości zmiennoprzecinkowych.W szczególności dwie wartości, które są równe teoretycznie może być nieznacznie różne reprezentacje.

Aby porównać ilości zmiennoprzecinkowe

  1. Obliczyć wartość bezwzględna różnicy ich przy użyciu Abs metoda Math klasy w System obszaru nazw.

  2. Dopuszczalna maksymalna różnica, należy określić takie, że można rozważyć dwie ilości są równe ze względów praktycznych, jeśli ich różnica jest większa.

  3. Porównać wartość bezwzględna różnicy do akceptowalnej różnicy.

W poniższym przykładzie zademonstrowano zarówno niepoprawne, jak i prawidłowe porównanie dwóch Double wartości.

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))

W poprzednim przykładzie użyto ToString metoda Double struktury, dzięki czemu można określić, z lepszą dokładność niż CStr wykorzystuje słowo kluczowe.Wartością domyślną jest 15 cyfr, ale format "G17" rozszerza ona 17 cyfr.

Operatora MOD zwraca dokładny wynik

Z niedokładności przechowywania liczb zmiennoprzecinkowych Mod — Operator (Visual Basic) może zwracać nieoczekiwany wynik, gdy co najmniej jeden z argumentów jest zmiennoprzecinkowych.

Decimal — Typ danych (Visual Basic) Nie używać reprezentacji liczb zmiennoprzecinkowych.Wiele numerów, które są niedokładne w Single i Double są dokładnie w Decimal (np. 0,2 i 0,3).Chociaż arytmetycznych jest wolniejszy w Decimal niż w zmiennoprzecinkowych, być może warto spadek wydajności do osiągnięcia lepszej dokładności.

Aby znaleźć całkowitą pozostałą część ilości zmiennoprzecinkowe

  1. Zadeklaruj zmienne jako Decimal.

  2. Należy użyć znaku typu literał D do wymuszenia literały do Decimal, w przypadku, gdy ich wartości są zbyt duże, aby Long typu danych.

W poniższym przykładzie zademonstrowano potencjału niedokładności zmiennoprzecinkowych operandów.

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))

W poprzednim przykładzie użyto ToString metoda Double struktury, dzięki czemu można określić, z lepszą dokładność niż CStr wykorzystuje słowo kluczowe.Wartością domyślną jest 15 cyfr, ale format "G17" rozszerza ona 17 cyfr.

Ponieważ zeroPointTwo jest Double, jego wartość 0,2 jest nieskończenie powtarzanej frakcji binarne, z przechowywana wartość 0.20000000000000001.Podzielenie 2.0 przez ilość ta daje 9.9999999999999995 z końca 0.19999999999999991.

W wyrażeniu dla decimalRemainder, znaku typu literał D wymusza oba operandy do Decimal, i 0,2 ma dokładne reprezentacji.Dlatego Mod operator daje oczekiwanego pozostałą część 0.0.

Należy zauważyć, że nie jest wystarczające, aby zadeklarować decimalRemainder jako Decimal.Należy również wymusić literały do Decimal, lub korzystają z Double domyślnie i decimalRemainder otrzymuje tę samą wartość niedokładne jako doubleRemainder.

Typ Boolean nie konwertować na typ liczbowy dokładnie

Boolean Data Type (Visual Basic)wartości nie są przechowywane jako liczby i wartości przechowywane nie są przeznaczone do równoważne liczb.Zgodność ze starszymi wersjami Visual Basic zawiera słowa kluczowe konwersji (CType — Funkcja (Visual Basic), CBool, CInt, i tak dalej) do konwersji między Boolean i typy liczbowe.Jednak inne języki czasami wykonywać te konwersje inaczej, tak jak .NET Framework metody.

Nigdy nie powinno się pisać kod, który opiera się na równoważne wartości liczbowe dla True i False.W każdym przypadku, gdy jest to możliwe, należy ograniczyć użycie Boolean zmiennych wartościami logicznymi, dla których są przeznaczone.Jeśli należy wymieszać Boolean i wartości liczbowych, upewnij się, że rozumiesz wybranej metody konwersji.

Konwersja z języka Visual Basic

Podczas używania CType lub CBool słowa kluczowe konwersji do konwersji typów danych liczbowych, aby Boolean, staje się 0 False i inne wartości stają się True.Podczas konwertowania Boolean wartości liczbowych typów za pomocą słów kluczowych konwersji, False staje się 0 i True staje się -1.

Konwersja w ramach

ToInt32 Metoda Convert klasy w System konwertuje obszaru nazw True do + 1.

Jeśli musisz przekonwertować Boolean wartość na typ danych numerycznych, należy zachować ostrożność o metody konwersji, którego używasz.

Znaków literałowych generuje błąd kompilatora

W przypadku braku jakichkolwiek znaków typu Visual Basic zakłada domyślne typy danych dla literałów.Domyślny typ dla literał znakowy — ujęty w cudzysłów (" ") — jest String.

String Typ danych nie poszerzyć do Char — Typ danych (Visual Basic).Oznacza to, że jeśli chcesz przypisać literał do Char zmiennej, należy wprowadzić konwersji zawężającej albo wymusić literału do Char typu.

Aby utworzyć Char literału, aby przypisać do zmiennej lub stała

  1. Zadeklarować zmienną lub stałą jako Char.

  2. Należy wpisać wartość znaku w cudzysłowach (" ").

  3. Wykonaj zamykającego znaku cudzysłowu podwójnego znakiem typu literał C do wymuszenia literału do Char.Jest to konieczne, jeśli sprawdzanie typu przełącznik (Option Strict — Instrukcja) jest On, i pożądane jest w każdym przypadku.

W poniższym przykładzie zademonstrowano pomyślne i niepomyślne przydziały literału do Char zmienna.

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")

Zawsze istnieje ryzyko w użyciu konwersji zawężającej, ponieważ może się nie powieść w czasie wykonywania.Na przykład, konwersja z String do Char może się nie powieść, jeśli String wartość zawiera więcej niż jeden znak.W związku z tym, lepiej jest programowania Aby użyć C należy wpisać znak.

Konwersja ciągu kończy się niepowodzeniem w czasie wykonywania

String — Typ danych (Visual Basic) Uczestniczy w bardzo niewielu poszerzanie konwersji.Stringrozszerza się do samego i Objecti tylko Char i Char() ( Char tablicy) są rozszerzane String.Wynika to z String zmiennych i stałych mogą zawierać wartości, które nie mogą zawierać innych typów danych.

Podczas sprawdzania typu przełączyć (Option Strict — Instrukcja) jest On, kompilator nie zezwala na wszystkie konwersje zawężającej.Obejmuje to te, które są udziałem String.Kod nadal można używać słów kluczowych konwersji np CStr i CType — Funkcja (Visual Basic), które bezpośrednio .NET Framework próba konwersji.

[!UWAGA]

Błąd konwersji zawężanie jest wstrzymany dla konwersji z elementów w For Each…Next kolekcji zmienna sterująca pętli.Aby uzyskać więcej informacji i przykłady, zobacz sekcję "Zawężanie konwersje" w For Each...Next — Instrukcja (Visual Basic).

Ochrona konwersji zawężającej

Zawężanie konwersje wadą jest to, że one się niepowodzeniem w czasie wykonywania.Na przykład jeśli String zmienna zawiera cokolwiek, inne niż "True" lub "Fałsz", nie można przekonwertować na Boolean.Jeśli zawiera znaki interpunkcyjne, konwersja na dowolny typ numeryczne nie powiedzie się.Jeśli nie wiesz, że Twój String zmienna zawsze przechowuje wartości, które mogą akceptować typu miejsca docelowego, nie należy spróbować konwersji.

Jeśli musisz przekonwertować z String na inny typ danych procedury najbezpieczniejsza jest należy ująć próba konwersji w Try...Catch...Finally — Instrukcja (Visual Basic).Umożliwia to zajmowania się błąd czasu wykonywania.

Tablice znaków

Pojedynczy Char i Tablica Char elementy zarówno poszerzyć, aby String.Jednakże String nie są rozszerzane Char().Aby przekonwertować String wartości do Char tablicy, można użyć ToCharArray metoda String klasy.

Wartości bez znaczenia

Ogólnie rzecz biorąc String wartości nie są znaczące w innych typów danych i konwersja jest wysoce sztuczne i niebezpiecznych.W każdym przypadku, gdy jest to możliwe, należy ograniczyć użycie String zmienne sekwencje znaków, dla których są przeznaczone.Nigdy nie powinno się pisać kod, który opiera się na wartości ekwiwalentne w przypadku innych typów.

Zobacz też

Informacje

Typ danych — Podsumowanie (Visual Basic)

Funkcje konwersji typu (Visual Basic)

Koncepcje

Typy danych w Visual Basic

Znaki typu

Typy wartości i odwołań

Skuteczne stosowanie typów danych (Visual Basic)

Inne zasoby

Konwersje plików w Visual Basic