Veri Türleri Sorunlarını Giderme (Visual Basic)

Bu sayfada, iç veri türlerinde işlem gerçekleştirdiğinizde oluşabilecek bazı yaygın sorunlar listelenir.

Floating-Point İfadeleri Eşit Olarak Karşılaştırmaz

Kayan noktalı sayılarla (Tek Veri Türü ve Çift Veri Türü) çalışırken bunların ikili kesirler olarak depolandığını unutmayın. Bu, ikili kesir olmayan herhangi bir miktarın (k / (2 ^ n) biçiminin tamsayılar olduğu herhangi bir miktarın tam gösterimini tutamayacakları anlamına gelir. Örneğin, 0,5 (= 1/2) ve 0,3125 (= 5/16) kesin değerler olarak tutulabilirken, 0,2 (= 1/5) ve 0,3 (= 3/10) yalnızca yaklaşık değerler olabilir.

Bu kesinlik nedeniyle, kayan nokta değerleri üzerinde çalışırken tam sonuçlara güvenemezsiniz. Özellikle, teorik olarak eşit olan iki değerin biraz farklı gösterimleri olabilir.

Kayan nokta miktarlarını karşılaştırmak için
1. Ad alanında sınıfının System yöntemini kullanarak Abs farklarının Math mutlak değerini hesaplayın.
2. Kabul edilebilir bir maksimum fark belirleyin, böylece farkları daha büyük değilse, pratik amaçlarla iki miktarı eşit olarak düşünebilirsiniz.
3. Farkın mutlak değerini kabul edilebilir farkla karşılaştırın.

Aşağıdaki örnekte iki Double değerin hem yanlış hem de doğru karşılaştırması gösterilmektedir.

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

Önceki örnek, anahtar sözcüğün ToStringDouble kullandığından daha iyi duyarlık belirtebilmesi için yapısının CStr yöntemini kullanır. Varsayılan değer 15 basamaktır, ancak "G17" biçimi bunu 17 basamağı genişletir.

Mod İşleci Doğru Sonuç Döndürmüyor

Kayan nokta depolamanın kesinsiz olması nedeniyle, işlenenlerden en az biri kayan nokta olduğunda Mod İşleci beklenmeyen bir sonuç döndürebilir.

Ondalık Veri Türü kayan nokta gösterimi kullanmaz. içinde olmayan ve Double tam olarak içinde Decimal olan birçok sayı Single (örneğin, 0,2 ve 0,3). Aritmetik, kayan noktadan daha yavaş olsa da Decimal , daha iyi duyarlık elde etmek için performans düşüşlerine değer olabilir.

Kayan nokta miktarlarının kalan tamsayısını bulmak için
1. Değişkenleri olarak Decimalbildirin.
2. Değerlerinin veri türü için çok büyük olması durumunda değişmez değerleri olarak zorlamak Decimaliçin Long değişmez değer türü karakterini D kullanın.

Aşağıdaki örnek, kayan nokta işlenenlerinin olası kesinliklerini gösterir.

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

Önceki örnek, anahtar sözcüğün ToStringDouble kullandığından daha iyi duyarlık belirtebilmesi için yapısının CStr yöntemini kullanır. Varsayılan değer 15 basamaktır, ancak "G17" biçimi bunu 17 basamağı genişletir.

olduğundan zeroPointTwoDouble, 0,2 değeri, 0,2000000000000000001 depolanmış değeriyle sonsuz yinelenen bir ikili kesirdir. 2,0'ın bu miktara bölünmesi 9,99999999999999999995 olur ve kalan değer 0,19999999999999991 olur.

için decimalRemainderifadesinde, değişmez değer türü karakteri D her iki işleneni de ile zorlar Decimalve 0,2 kesin bir temsile sahiptir. Bu nedenle Mod işleç beklenen kalan 0,0 değerini verir.

olarak Decimalbildirmenin decimalRemainder yeterli olmadığını unutmayın. Sabit değerleri Decimaliçin de zorlamalısınız veya varsayılan olarak kullanır Double ve decimalRemainder ile aynı yanlış değeri doubleRemainderalır.

Boole Türü Sayısal Türe Doğru Dönüştürülmüyor

Boole Veri Türü değerleri sayı olarak depolanmaz ve depolanan değerlerin sayılarla eşdeğer olması amaçlanmamıştır. Visual Basic, önceki sürümlerle uyumluluk için ve sayısal türler arasında Boolean dönüştürme yapmak için dönüştürme anahtar sözcükleri (CType İşlevi, CBool, CIntvb.) sağlar. Ancak, diğer diller bazen .NET Framework yöntemleri gibi bu dönüştürmeleri farklı şekilde gerçekleştirir.

ve Falseiçin True eşdeğer sayısal değerlere dayalı kod yazmamalısınız. Mümkün olduğunda, değişkenlerin Boolean kullanımını tasarlandıkları mantıksal değerlerle kısıtlamanız gerekir. ve sayısal değerleri karıştırmanız Boolean gerekiyorsa, seçtiğiniz dönüştürme yöntemini anladığınızdan emin olun.

Visual Basic'te Dönüştürme

sayısal veri türlerini Booleanöğesine dönüştürmek için veya CBool dönüştürme anahtar sözcüklerini kullandığınızdaCType, 0 olur False ve diğer tüm değerler olurTrue. Dönüştürme anahtar sözcüklerini kullanarak değerleri sayısal türlere dönüştürdüğünüzde Boolean , False 0 olur ve True -1 olur.

Çerçevede Dönüştürme

ToInt32 Ad alanında System sınıfının yöntemi Convert +1'e dönüştürülürTrue.

Bir Boolean değeri sayısal veri türüne dönüştürmeniz gerekiyorsa, hangi dönüştürme yöntemini kullandığınıza dikkat edin.

Karakter Değişmez Değeri Derleyici Hatası Oluşturuyor

Herhangi bir tür karakteri olmadığında, Visual Basic değişmez değerler için varsayılan veri türlerini varsayar. Karakter değişmez değeri için varsayılan tür (tırnak işareti (" ") içine alınmış) şeklindedir String.

Veri String türü Char Veri Türüne genişletilmez. Başka bir deyişle, bir Char değişkene değişmez değer atamak istiyorsanız, bir daraltma dönüştürmesi yapmanız veya sabit değeri türe Char zorlamanız gerekir.

Bir değişkene veya sabite atanacak bir Char değişmez değeri oluşturmak için
1. Değişken veya sabiti olarak Charbildirin.
2. Karakter değerini tırnak işareti (" ") içine alın.
3. Değişmez değeri olarak zorlamak Chariçin değişmez değer türü karakteriyle C kapanış çift tırnak işaretini izleyin. Tür denetimi anahtarı (Option Strict Statement) ise Onve her durumda isteniyorsa bu gereklidir.

Aşağıdaki örnek, bir değişmez değerin bir değişkene hem başarısız hem de başarılı atamalarını Char gösterir.

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

Çalışma zamanında başarısız olabilecekleri için daraltma dönüştürmelerini kullanmanın her zaman bir riski vardır. Örneğin, StringChar değerin birden fazla karakter içermesi String durumunda dönüştürme işlemi başarısız olabilir. Bu nedenle, tür karakterini kullanmak C daha iyi programlamadır.

Dize Dönüştürme Çalışma Zamanında Başarısız Oluyor

Dize Veri Türü çok az genişletme dönüştürmesine katılır. String yalnızca kendisine ve Objectile genişletir ve yalnızca Char ve Char() (dizi Char ) ile genişletir String. Bunun nedeni String değişkenlerin ve sabitlerin diğer veri türlerinin içeremeyeceği değerler içerebileceğindendir.

Tür denetimi anahtarı (Option Strict Deyimi) olduğunda On, derleyici tüm örtük daraltma dönüştürmelerine izin vermemektedir. Bu, içerenleri Stringiçerir. Kodunuz, .NET Framework dönüştürmeyi denemeye yönlendiren ve CType İşlevi gibi CStr dönüştürme anahtar sözcüklerini kullanmaya devam edebilir.

Not

Bir koleksiyondaki For Each…Next öğelerden döngü denetimi değişkenine dönüştürmeler için daraltma-dönüştürme hatası gizleniyor. Daha fazla bilgi ve örnek için , For Each... bölümündeki "Dönüştürmeleri Daraltma" bölümüne bakın. Next Deyimi.

Dönüştürme Korumasını Daraltma

Dönüştürmeleri daraltma dezavantajı, çalışma zamanında başarısız olmalarıdır. Örneğin, bir değişken "Doğru" veya "Yanlış" dışında bir String şey içeriyorsa, değişkenine Booleandönüştürülemez. Noktalama karakterleri içeriyorsa, herhangi bir sayısal türe dönüştürme başarısız olur. Değişkeninizin String her zaman hedef türün kabul edebildiği değerleri barındırdığını bilmiyorsanız, dönüştürmeyi denememelisiniz.

'den String başka bir veri türüne dönüştürmeniz gerekiyorsa, en güvenli yordam deneme dönüştürmeyi Try... içine almaktır. Yakalamak... Finally Deyimi. Bu, çalışma zamanı hatasıyla başa çıkmanızı sağlar.

Karakter Dizileri

Hem tek Char bir hem de bir öğe dizisi Char olarak genişletir String. Ancak, String genişletilmez Char(). Bir String değeri diziye Char dönüştürmek için sınıfının yöntemini System.String kullanabilirsinizToCharArray.

Anlamsız Değerler

Genel olarak, String değerler diğer veri türlerinde anlamlı değildir ve dönüştürme son derece yapay ve tehlikelidir. Mümkün olduğunda, değişkenlerin String kullanımını tasarlandıkları karakter dizileriyle kısıtlamanız gerekir. Hiçbir zaman diğer türlerdeki eşdeğer değerlere dayalı kod yazmamalısınız.

Ayrıca bkz.