Belajar Bahasa C sharp/Bab IV: Perbedaan antara revisi

Konten dihapus Konten ditambahkan
Willysaef (bicara | kontrib)
Willysaef (bicara | kontrib)
Baris 175:
Dan hasilnya adalah 501.334.399, yang berarti hasil perkalian dari 43.046.721 dengan dirinya sendiri akan dipotong menjadi 32-bit, yakni -501.334.399. Coba lihat, berapa hasilnya? Sama tidak?
==Overflow dan Underflow==
Kok, ada anomali ya? Katanya komputer barang yang canggih, tapi kenapa ya? Sebelumnya saya pernah katakan bahwa komputer adalah barang yang bego, yang tidak akan bergerak tanpa ada instruksi! Komputer, hanya bisa kita anggap sebagai budak saja lah. Lalu kenapa terjadi anomali, karena di sana terjadi apa yang disebut dengan '''''<u>overflow</u>''''' dan '''''<u>underflow</u>'''''. Nah lho apa lagi tuh? Kejadian ''overflow'' akan terjadi saat nilai sebuah bilangan bulat melebihi nilai positif maksimumnya, sementara ''underflow'' akan terjadi saat nilai sebuah bilangan bulat kurang dari nilai negatif minimumnya. Tapi, para ''programmer'' seringnya menggunakan kata "'''''overflow'''''" saja untuk menjelaskan kedua fenomena tersebut. Program-program C# pada dasarnya mengizinkan adanya ''overflow'', karena C# dapat melakukan penjumlahan, pengurangan perkalian, dan pembagian terhadap bilangan bulat tanpa adanya kekhawatiran apakah nantinya hasilnya dapat ditampung pada ruangan 32-bit atau tidak. Mengabaikan overflow dalam melakukan perhitungan aritmetika terhadap bilangan bulat adalah sebuah cara yang paling efisien dan paling cepat dilakukan oleh komputer. Komputer, namanya saja budak bego, akan terus saja meneruskan perhitungan tersebut tanpa harus berhenti sejenak untuk mengecek apakah terjadi ''overflow'' atau tidak.
 
Meskipun beberapa program aplikasi mungkin dapat mengambil keuntungan dari overflow bilangan bulat, dalam banyak kasus, ''overflow'' menjadi sebuah masalah dan dianggap menjadi sebuah ''bug'' di dalam kode kita. Sebagai contoh, program sebuah bank yang menerima uang hingga miliaran rupiah, adalah sebuah program yang tidak menerima overflow, karena ketika seorang nasabah memiliki hutang -2.147.483.647 rupiah dalam saldo, lalu ada bunga 1 rupiah, maka saldonya akan berubah menjadi 2.147.483.648, yang berarti hal tersebut berubah menjadi keuntungan buat si penghutang tersebut. Siapa penjahatnya? Bukannya teller atau kasir, tapi ''overflow'' lah yang jadi penjahatnya.
Baris 181:
Teknik pertama melibatkan kompiler C# itu sendiri. Kita dapat menginstruksikan kompiler C# untuk membuat kode yang mampu melakukan pengecekan terhadap ''overflow'' terhadap bilangan bulat. Ini merupakan contoh dari opsi kompiler. Untuk mengilustrasikannya, marilah kita kembali ke contoh program Program0201.cs.
 
Jika kita menggunakan Microsoft Visual Studio atau Microsoft Visual C# Express Edition, bukalah jendela properti Program0201 dengan cara mengklik kanan pada proyek yang bersangkutan lalu memilih menu Properties. Pada Project Properties yang keluar selanjutnya, bukalah tab '''Build'''. Di sana ada sebuah tombol '''Advanced''', dan tekanlah tombol tersebut untuk memunculkan '''Advanced Build Settings''' seperti yang terlihat pada gambar berikut. Centanglah '''checkbox Check for arithmetic overflow/underflow'''. Lalu tekan OK untuk menutup kotak dialog tersebut.
 
[[Berkas:BelajarCSharp-403.gif|Konfigurasi checking ''overflow''/''underflow'']]
 
Lakukan kompilasi, dan jalankan programnya. Saat program Program0201 berjalan, program tersebut akan menampilkan lima buah baris pertama, sebelum akhirnya akan memunculkan sebuah eksepsi.
 
[[Berkas:BelajarCSharp-404.gif|Program berjalan saat pengecekan ''overflow'']]
 
Kita juga sebenarnya bisa melakukan pengecekan terhadap overflow pada ekspresi-ekspresi secara individual di dalam kode sumber dengan menggunakan operator checked. Statemen berikut:
<source lang="csharp">
B = checked(5 * A);
</source>
akan mengeluarkan sebuah eksepsi, meskipun kita telah membuang tanda centang pada opsi '''Check for arithmetic overflow/underflow''', jika memang di dalam ekspresi tersebut akan menghasilkan sebuah nilai yang berada di luar jangkauan. Lawan dari operator <code>checked</code> adalah <code>unchecked</code>, sehingga ekspresi di atas diubah menjadi seperti:
<source lang="csharp">
B = unchecked(5 * A);
</source>
sehingga ekspresi tersebut tidak akan mengeluarkan eksepsi, meski opsi Check for arithmetic overflow/underflow kita telah centang.
 
Kita juga bisa menggunakan operator <code>checked</code> dan <code>unchecked</code> dalam sebuah blok kode (yang diapit oleh tanda kurung keriting <code>{</code> dan <code>}</code>). Perhatikan contoh berikut:
<source lang="csharp">
checked
{
A += 1000000;
B = B * A;
}
</source>
Setiap statemen yang berada di dalam blok tersebut yang nantinya akan menghasilkan ''overflow'' dalam operasi aritmetika akan mengeluarkan eksepsi. Operator unchecked juga bisa digunakan sebagai lawan dari <code>checked</code>.
 
Pilihan ketiga adalah dengan menggunakan pilihan kompiler C# (csc.exe) dengan tambahan ''switch'' <code>/checked+</code> untuk mengaktifkan proses pengecekan atau <code>/checked-</code> untuk menonaktifkan proses pengecekan.
 
csc.exe Program0201.cs /checked+
 
(perintah ini sama saja dengan opsi Check for arithmetic overflow/underflow dalam SharpDevelop atau IDE lainnya.)
 
Jadi, kita punya banyak pilihan. Kita juga bisa mengizinkan kalkulasi aritmetika untuk terus maju tanpa memperhatikan kemunculan overflow (yang mungkin akan menyebabkan kesalahan di dalam hasilnya), atau kita bisa menghentikan kalkulasi seperti ini untuk menyebabkan sebuah eksepsi. Untuk saat ini, memang tidak ada pilihan lagi, karena memang eksepsi bisa menghentikan proses eksekusi program. (sebenarnya ada sebuah cara tentang bagaimana sebuah program dapat mendeteksi kapan eksepsi dapat dimunculkan dan dapat kembali ke dalam proses eksekusi saat program selesai melakukan eksekusi. Tapi saat ini kita belajar ini dulu saja ya).
 
Mungkin, kita berkata "ah lebih baik gunakan opsi <code>/checked+</code> saja lah, biar nantinya program yang saya buat nggak akan muncul ''overflow'', toh overflow akan mematikan program saya!" Jujur saja, saya menentang hal tersebut! Mengaktifkan pengecekan ''overflow'' untuk semua operasi aritmetika dapat menurunkan performa dan kecepatan program yang kita buat. Oke, yang saya tentang adalah ketika kita membuat program untuk didistribusikan ke pengguna, kita mengaktifkan opsi pengecekan ''overflow'', tapi saat kita mengembangkan program kita, ya nggak apa-apa lah! Toh yang menggunakan program, kita-kita juga. Saran saya, gunakan saja operator <code>checked</code> dan unchecked pada statemen dan ekspresi yang mungkin akan membuat eksepsi ''overflow'', daripada menggunakan opsi <code>/checked+</code> atau <code>/checked-</code>, sebelum kita belajar mengenai penangan eksepsi secara lebih elegan!
==Bilangan Bulat Bertanda==
Whew! Mungkin yang ada di dalam pikiran kita, kenapa sih saya menggunakan int melulu seolah-olah C# hanya mendukung <code>int</code>? Oke deh. Saya kembali ke jalan lagi. Tipe data <code>int</code> memang merupakan tipe data yang paling populer, akan tetapi sebenarnya, C# mendukung keberadaan tipe data lainnya lho.
 
Anggap kita sedang menangani data populasi manusia di Indonesia. Pasti, tidak ada penduduk yang dianggap negatif oleh komputer, sehingga kenapa juga kita menggunakan ''signed integer''? Lagian, kita juga nggak bakal menggunakan setengah nilai dari total nilai yang disediakan oleh ''signed integer'' (berarti semiliar data, wow! Padahal Indonesia kan cuma 250 juta jiwa doang). Lalu, apa dong yang bisa digunakan? Kita bisa menggunakan ''unsigned integer'' (bilangan bulat tidak bertanda), ketimbang kita menggunakan bilangan ''signed integer'' (bilangan bulat bertanda).
 
Bahasa C# mendukung tipe data bilangan bulat tidak bertanda berukuran 32-bit, yang disebut dengan <code>uint</code>. Cara bacanya: "you int". Kita bisa mendeklarasikan uint sebagaimana kita mendeklarasikan <code>int</code>, dengan cara:
<source lang="csharp">uint A;</source>
Bilangan bulat tak bertanda tidak memiliki bit penanda (sign bit). Bit yang paling kiri (''most significant bit'') akan dianggap sama seperti halnya bit yang lain. Seperti halnya <code>int</code>, <code>uint</code> juga dimulai dari 0:
 
0000-0000-0000-0000-0000-0000-0000-0000
 
Dan terus menerus naik hingga nilai maksimum dari <code>int</code>:
 
0111-1111-1111-1111-1111-1111-1111-1111 atau setara dengan 2.147.483.647
 
Akan tetapi, tidak seperti <code>int</code>, <code>uint</code> akan terus menerus mendapatkan nilai positif:
 
1000-0000-0000-0000-0000-0000-0000-0000 atau setara dengan 2.147.483.648
 
Hingga nilai maksimum positifnya:
 
1111-1111-1111-1111-1111-1111-1111-1111 atau setara dengan 4.294.967.295
 
sehingga, tipe data uint dapat menyimpan nilai dari 0 hingga 4.294.967.295 (2<sup>32</sup>-1). Sebuah tipe data <code>uint</code> saat ini mampu menangani data populasi orang Indonesia, dan mungkin semua negara di dunia. Akan tetapi, saat harus menghadapi jumlah populasi seluruh manusia di Bumi, uint pun takluk!
 
Sama seperti tipe data int, uint juga dapat terkena "kutukan" overflow dan underflow. Perhatikan contoh di bawah ini:
<source lang="csharp">
uint A = 4294967295;
A += 1;
</source>
Variabel A akan menghasilkan nilai 0 jika pengecekan overflow terhadap integer tidak dilakukan, atau bernilai 1 saat pengecekan overflow dilakukan.
 
{{stub}}