Megosztás a következőn keresztül:


Adattípusok hibaelhárítása (Visual Basic)

Ez a lap felsorol néhány gyakori problémát, amelyek akkor fordulhatnak elő, ha belső adattípusokon hajt végre műveleteket.

Floating-Point kifejezések nem egyenlők

Amikor lebegőpontos számokkal (egy adattípussal és dupla adattípussal) dolgozik, ne feledje, hogy ezek bináris törtekként vannak tárolva. Ez azt jelenti, hogy nem tartalmazhatnak olyan mennyiség pontos ábrázolását, amely nem bináris tört (k / (2 ^ n) formában, ahol k és n egész szám. A 0,5 (= 1/2) és a 0,3125 (= 5/16) például pontos értékekként tartható meg, míg a 0,2 (= 1/5) és a 0,3 (= 3/10) csak közelítések lehetnek.

Emiatt a pontatlanság miatt nem támaszkodhat pontos eredményekre lebegőpontos értékek használatakor. Különösen két, elméletileg egyenlő értéknek lehetnek kissé eltérő ábrázolásai.

Lebegőpontos mennyiségek összehasonlítása
1. Számítsa ki a különbség abszolút értékét a Abs névtérben lévő System osztály metódusávalMath.
2. Határozzon meg egy elfogadható maximális különbséget, így a két mennyiség gyakorlati szempontból egyenlőnek tekinthető, ha a különbségük nem nagyobb.
3. Hasonlítsa össze a különbség abszolút értékét az elfogadható különbségével.

Az alábbi példa két Double érték helytelen és helyes összehasonlítását mutatja be.

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

Az előző példa a ToString struktúra metódusát Double használja, hogy nagyobb pontosságot adjon meg, mint a CStr kulcsszó. Az alapértelmezett érték 15 számjegy, de a "G17" formátum 17 számjegyre bővíti.

A modoperátor nem ad vissza pontos eredményt

A lebegőpontos tárolás pontatlansága miatt a Mod Operátor váratlan eredményt adhat vissza, ha az operandusok közül legalább az egyik lebegőpontos.

A decimális adattípus nem használ lebegőpontos ábrázolásokat. Sok olyan szám, amely nem létezik Single , és Double pontosak Decimal (például 0,2 és 0,3). Bár az aritmetika lassabb Decimal , mint a lebegőpontos, érdemes lehet a teljesítménycsökkenést a jobb pontosság érdekében.

A lebegőpontos mennyiségek fennmaradó egész számának megkeresése
1. Változók deklarálása Decimal.
2. A literál típusú karakter D használatával kényszerítse a literálokat Decimalarra az esetre, ha az értékük túl nagy az Long adattípushoz.

Az alábbi példa a lebegőpontos operandusok lehetséges pontatlanságát mutatja be.

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

Az előző példa a ToString struktúra metódusát Double használja, hogy nagyobb pontosságot adjon meg, mint a CStr kulcsszó. Az alapértelmezett érték 15 számjegy, de a "G17" formátum 17 számjegyre bővíti.

Mivel zeroPointTwo a Double0,2 értéke végtelenül ismétlődő bináris tört 0,200000000001 tárolt értékkel. A 2,0-t ezzel a mennyiséggel 9,9999999999999999999999995 osztva a 0,1999999999991 fennmaradó részével.

A kifejezésben decimalRemaindera literális típusú karakter D mindkét operandusra Decimalkényszeríti az operandusokat, a 0.2 pedig pontos ábrázolású. Ezért az Mod operátor a várt 0,0-s maradékot adja.

Vegye figyelembe, hogy a deklarálása decimalRemainderDecimalnem elegendő. A literálokat arra is kényszerítenie kell, vagy alapértelmezés szerint használják DecimalDouble őket, és decimalRemainder ugyanazt a pontatlan értéket kapja, mint a doubleRemainder.

A logikai típus nem konvertálja pontosan numerikus típussá

A logikai adattípus értékei nem számokként vannak tárolva, és a tárolt értékek nem a számoknak adhatók meg. A korábbi verziókkal való kompatibilitás érdekében a Visual Basic konverziós kulcsszavakat (CType OperátorCBool stbCInt.) biztosít a között és a numerikus típusok közötti Boolean konvertáláshoz. Más nyelvek azonban néha másképp hajtják végre ezeket az átalakításokat, mint a .NET-keretrendszer metódusai.

Soha ne írjon olyan kódot, amely a megfelelő numerikus értékekre True támaszkodik.False Amikor csak lehetséges, a változók használatát Boolean azokra a logikai értékekre kell korlátoznia, amelyekhez azokat tervezték. Ha vegyes és numerikus értékeket kell használnia Boolean , győződjön meg arról, hogy ismeri a választott konverziós módszert.

Konvertálás a Visual Basicben

Ha a numerikus adattípusokat a CType 0 False értékre konvertálja, és CBool az összes többi érték Truelesz.Boolean Ha az értékeket numerikus típussá konvertálja Boolean a konverziós kulcsszavak használatával, 0 lesz, False és True -1 lesz.

Átalakítás a keretrendszerben

A ToInt32 névtér True osztályának System metódusa Convert +1 lesz.

Ha egy értéket numerikus adattípussá kell konvertálnia Boolean , ügyeljen arra, hogy melyik konverziós módszert használja.

A karakterkonstans fordítási hibát okoz

Típuskarakterek hiányában a Visual Basic a literálok alapértelmezett adattípusait feltételezi. A karakterkonstansok alapértelmezett típusa – idézőjelek (" ") közé zárva – az String.

Az String adattípus nem szélesedik ki a Karakter adattípusra. Ez azt jelenti, hogy ha konstanst szeretne hozzárendelni egy Char változóhoz, akkor vagy szűkítő konverziót kell végeznie, vagy a literált a Char típusra kell kényszerítenie.

Karakterkonstans létrehozása változóhoz vagy állandóhoz való hozzárendeléshez
1. Deklarálja a változót vagy az állandót Char.
2. A karakter értékét idézőjelek közé kell foglalni (" ").
3. Kövesse a záró dupla idézőjelet a literál típusú karakterrel C , hogy a literálist a következőre kényszerítse Char. Erre akkor van szükség, ha a típus-ellenőrző kapcsoló (Option Strict Statement) az On, és ez minden esetben kívánatos.

Az alábbi példa egy változóhoz tartozó literál Char sikertelen és sikeres hozzárendeléseit mutatja be.

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

A szűkülő konverziók használata mindig fennáll, mert futásidőben sikertelenek lehetnek. A konvertálás StringChar például meghiúsulhat, ha az String érték egynél több karaktert tartalmaz. Ezért jobb programozni a típus karaktert C .

A sztringek konvertálása futásidőben meghiúsul

A sztring adattípusa nagyon kevés szélesítő konverzióban vesz részt. Stringcsak önmagára szélesít, és Objectcsak Char és Char() (tömbChar) szélesedik.String Ennek az az oka, hogy String a változók és az állandók olyan értékeket tartalmazhatnak, amelyeket más adattípusok nem tartalmazhatnak.

Ha a típus-ellenőrző kapcsoló (Option Strict Statement) az On, a fordító nem engedélyezi az összes implicit szűkítési konverziót. Ide tartoznak a következők String: . A kód továbbra is használhat konverziós kulcsszavakat, például CStr a CType Operátort, amely a .NET-keretrendszert az átalakítás megkísérlésére utasítja.

Megjegyzés:

A szűkítés-konverziós hiba el lesz tiltva a gyűjtemény elemeiből For Each…Next a ciklusvezérlő változóba való konvertáláskor. További információkért és példákért tekintse meg a "Konvertálások szűkítése" szakaszt az Egyes... Következő utasítás.

A konverziós védelem szűkítése

A konverziók szűkítésének hátránya, hogy futásidőben meghiúsulhatnak. Ha például egy String változó nem "Igaz" vagy "Hamis" értéket tartalmaz, akkor nem konvertálható Boolean. Ha írásjeleket tartalmaz, a numerikus típusra való konvertálás sikertelen. Ha nem tudja, hogy a String változó mindig olyan értékeket tartalmaz, amelyeket a céltípus elfogadhat, ne próbálkozzon átalakítással.

Ha át kell alakítania String egy másik adattípusra, a legbiztonságosabb eljárás az, hogy a megkísérelt átalakítást a Try... Elkap... Végül nyilatkozat. Ez lehetővé teszi a futásidejű hibák kezelését.

Karaktertömbök

Egyetlen Char és egy elemtömb Char is ki van szélesedve String. String Azonban nem szélesedik a Char(). Az érték Char tömbké alakításához String használhatja az ToCharArraySystem.String osztály metódusát.

Jelentés nélküli értékek

Az értékek általában String nem értelmezhetők más adattípusokban, az átalakítás pedig rendkívül mesterséges és veszélyes. Amikor csak lehetséges, korlátoznia kell a változók használatát String azokra a karaktersorozatokra, amelyekhez azokat tervezték. Soha ne írjon olyan kódot, amely más típusok egyenértékű értékeire támaszkodik.

Lásd még