Bagikan melalui


Pemecahan Masalah Tipe Data (Visual Basic)

Halaman ini mencantumkan beberapa masalah umum yang dapat terjadi ketika Anda melakukan operasi pada jenis data intrinsik.

Ekspresi Floating-Point Jangan Bandingkan sebagai Sama

Saat Anda bekerja dengan angka floating-point (Jenis Data Tunggal dan Jenis Data Ganda), ingatlah bahwa angka tersebut disimpan sebagai pecahan biner. Ini berarti mereka tidak dapat memegang representasi yang tepat dari kuantitas apa pun yang bukan pecahan biner (dari bentuk k/(2 ^ n) di mana k dan n adalah bilangan bulat). Misalnya, 0,5 (= 1/2) dan 0,3125 (= 5/16) dapat ditahan sebagai nilai yang tepat, sedangkan 0,2 (= 1/5) dan 0,3 (= 3/10) hanya dapat berupa perkiraan.

Karena ketidaktepatan ini, Anda tidak dapat mengandalkan hasil yang tepat ketika Anda beroperasi pada nilai floating-point. Secara khusus, dua nilai yang secara teoritis sama mungkin memiliki representasi yang sedikit berbeda.

Untuk membandingkan jumlah floating-point
1. Hitung nilai absolut perbedaannya dengan menggunakan metode Abs kelas Math di namespace layanan System.
2. Tentukan perbedaan maksimum yang dapat diterima, sehingga Anda dapat menganggap dua kuantitas tersebut sama untuk tujuan praktis jika perbedaannya tidak lebih besar.
3. Bandingkan nilai absolut perbedaan dengan perbedaan yang dapat diterima.

Contoh berikut menunjukkan perbandingan dua nilai Double yang salah dan benar.

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

Contoh sebelumnya menggunakan metode ToString struktur Double sehingga dapat menentukan presisi yang lebih baik daripada yang digunakan kata kunci CStr. Defaultnya adalah 15 digit, tetapi format "G17" memperluasnya menjadi 17 digit.

Operator mod tidak mengembalikan hasil yang akurat

Karena ketidaktepatan penyimpanan floating-point, Operator Mod dapat mengembalikan hasil yang tidak terduga ketika setidaknya salah satu operand adalah floating-point.

Tipe Data Desimal tidak menggunakan representasi floating-point. Banyak angka yang tidak tepat pada Single dan Double persis di Decimal (misalnya 0,2 dan 0,3). Meskipun aritmatika lebih lambat dalam Decimal daripada di floating-point, mungkin sepadan dengan penurunan performa untuk mencapai presisi yang lebih baik.

Untuk menemukan sisa bilangan bulat dari jumlah floating-point
1. Mendeklarasikan variabel sebagai Decimal.
2. Menggunakan D karakter jenis harfiah untuk memaksa harfiah ke Decimal, jika nilainya terlalu besar untuk jenis data Long.

Contoh berikut menunjukkan potensi impresi operan floating-point.

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

Contoh sebelumnya menggunakan metode ToString struktur Double sehingga dapat menentukan presisi yang lebih baik daripada yang digunakan kata kunci CStr. Defaultnya adalah 15 digit, tetapi format "G17" memperluasnya menjadi 17 digit.

Karena zeroPointTwo adalah Double, nilainya untuk 0,2 adalah pecahan biner berulang tanpa batas dengan nilai tersimpan 0,20000000000000000001. Pembagian 2,0 dengan tangguhan kuantitas ini 9,999999999999999995 dengan sisa 0,199999999999999991.

Dalam ekspresi untuk decimalRemainder, D karakter jenis harfiah memaksa kedua operand ke Decimal, dan 0,2 memiliki representasi yang tepat. Oleh karena itu operator Mod menangguhkan sisa yang diharapkan 0,0.

Perhatikan bahwa tidak cukup untuk menyatakan decimalRemainder sebagai Decimal. Anda juga harus memaksa harfiah untuk Decimal, atau mereka menggunakan Double secara default dan decimalRemainder menerima nilai yang tidak akurat yang sama dengan doubleRemainder.

Jenis Boolean Tidak Dikonversi ke Jenis Numerik Secara Akurat

Nilai Tipe Data Boolean tidak disimpan sebagai angka, dan nilai yang disimpan tidak dimaksudkan setara dengan angka. Untuk kompatibilitas dengan versi yang lebih lama, Visual Basic menyediakan kata kunci konversi (Fungsi CType, CBool, CInt, dan sebagainya) untuk mengonversi antara Boolean dan jenis numerik. Namun, bahasa pemrogram lain terkadang melakukan konversi ini secara berbeda, seperti halnya metode .NET Framework.

Anda tidak boleh menulis kode yang bergantung pada nilai numerik yang setara untuk True dan False. Jika memungkinkan, Anda harus membatasi penggunaan variabel Boolean ke nilai logis yang dirancang. Jika Anda harus mencampur Boolean dan nilai numerik, pastikan Anda memahami metode konversi yang Anda pilih.

Konversi dalam Visual Basic

Saat Anda menggunakan CType atau kata kunci konversi CBool untuk mengonversi jenis data numerik menjadi Boolean, 0 menjadi False dan semua nilai lainnya menjadi True. Saat Anda mengonversi nilai Boolean menjadi jenis numerik dengan menggunakan kata kunci konversi, False menjadi 0 dan True menjadi -1.

Konversi dalam Kerangka Kerja

Metode ToInt32 kelas Convert di namespace layanan System dikonversi menjadi +1 True.

Jika Anda harus mengonversi nilai Boolean menjadi jenis data numerik, berhati-hatilah dengan metode konversi mana yang Anda gunakan.

Harfiah Karakter Menghasilkan Kesalahan Kompilator

Dengan tidak adanya karakter jenis apa pun, Visual Basic mengasumsikan jenis data default untuk harfiah. Jenis default untuk harfiah karakter— yang diapit dalam tanda kutip (" ") — adalah String.

Jenis data String tidak melebar ke Jenis Data Char. Ini berarti bahwa jika Anda ingin menetapkan harfiah ke variabel Char, Anda harus membuat konversi yang mempersempit atau memaksa harfiah ke jenis tersebut Char.

Untuk membuat Char literal untuk ditetapkan ke variabel atau konstanta
1. Deklarasikan variabel atau konstanta sebagai Char.
2. Sertakan nilai karakter dalam tanda kutip (" ").
3. Ikuti tanda kutip ganda penutup dengan C karakter jenis harfiah untuk memaksa harfiah ke Char. Ini diperlukan jika pengganti pemeriksaan jenis (Pernyataan Ketat Opsi) adalah On, dan diinginkan dalam kasus apa pun.

Contoh berikut menunjukkan penugasan harfiah yang tidak berhasil dan berhasil ke variabel Char.

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

Selalu ada risiko dalam menggunakan konversi yang mempersempit, karena dapat gagal pada durasi. Misalnya, konversi dari String ke Char dapat gagal jika nilai String berisi lebih dari satu karakter. Oleh karena itu, lebih baik pemrograman untuk menggunakan karakter jenis C.

Konversi String Gagal pada Durasi

Jenis Data String berpartisipasi dalam sangat sedikit konversi yang melebar. String hanya melebar ke dirinya sendiri dan Object, dan hanya Char dan Char() (array Char) melebar ke String. Ini karena variabel String dan konstanta dapat berisi nilai yang tidak dapat dimuat oleh jenis data lain.

Ketika sakelar pemeriksaan jenis (Pernyataan Ketat Opsi) adalah On, kompilator melarang semua konversi penyempitan implisit. Ini termasuk yang melibatkan String. Kode Anda masih dapat menggunakan kata kunci konversi seperti CStr dan Fungsi CType, yang mengarahkan .NET Framework untuk mencoba konversi.

Catatan

Kesalahan konversi penyempitan ditekan untuk konversi dari elemen dalam koleksi For Each…Next ke variabel kontrol perulangan. Untuk informasi dan contoh selengkapnya, lihat bagian "Mempersempit Konversi" di Untuk Setiap... Pernyataan Berikutnya.

Mempersempit Perlindungan Konversi

Kerugian dari mempersempit konversi adalah bahwa mereka dapat gagal pada durasi. Misalnya, jika variabel String berisi apa pun selain "True" atau "False," variabel tersebut tidak dapat dikonversi ke Boolean. Jika berisi karakter tanda baca, konversi ke jenis numerik apa pun gagal. Kecuali Anda tahu bahwa variabel String Anda selalu menyimpan nilai yang jenis tujuan dapat terima, Anda tidak boleh mencoba konversi.

Jika Anda harus mengonversi dari String ke jenis data lain, prosedur teraman adalah mengapit konversi yang dicoba di Coba... Menangkap... Pernyataan Terakhir. Ini memungkinkan Anda berurusan dengan kegagalan run-time.

Array Karakter

Char Satu dan array elemen Char keduanya melebar ke String. Namun, String tidak melebar ke Char(). Untuk mengonversi nilai String menjadi array Char, Anda dapat menggunakan metode ToCharArray dari kelas System.String.

Nilai Yang Tidak Berarti

Secara umum, nilai String tidak bermakna dalam jenis data lain, dan konversi sangat buatan dan berbahaya. Jika memungkinkan, Anda harus membatasi penggunaan variabel String ke urutan karakter yang dirancang. Anda tidak boleh menulis kode yang bergantung pada nilai yang setara dalam jenis lain.

Lihat juga