Konversi Tipe Data Dalam Pemrograman C#

Konversi Tipe Data

Halo! Selamat datang kembali di “Seri Belajar Dasar Pemrograman Bahasa C#“. Pada materi sebelumnya, Anda sudah mempelajari tentang bagaimana bekerja dengan tipe data string di C#. Materi yang cukup panjang, bukan?

Kali ini, kita akan mempelajari bagaimana mengubah nilai variabel dari tipe data tertentu menjadi nilai variabel dari tipe data yang lain. Untuk mempelajari materi ini, pastikan Anda sudah memahami apa itu tipe data dan variabel.

Setelah mempelajari materi ini, Anda akan memahami kapan sebuah tipe bisa dikonversi secara implisit dan kapan konversi eksplisit harus dilakukan. Selain itu, Anda juga akan mengerti cara menggunakan beberapa operasi bawaan C# yang bisa digunakan untuk mengkonversi tipe data. Terakhir, Anda juga akan mengerti bagaimana melakukan parsing terhadap sebuah masukan dari tipe string dan mengkonversinya ke tipe data yang diperlukan.

Apa Perlunya Mengkonversi Tipe Data?

Ketika kita sudah mendeklarasikan sebuah variabel dari tipe data tertentu, terkadang setelahnya kita perlu merubah tipe data dari nilai yang disimpan di dalam variabel tersebut ke tipe data yang lain. 

Katakanlah kita diminta untuk membuat aplikasi kalkulator sederhana. Input angka dari keyboard yang diberikan oleh pengguna aplikasi tersebut sebenarnya masih berupa sebuah teks (tipe data string). Namun, kita ingin menggunakan nilai input tersebut untuk melakukan operasi aritmatika seperti penjumlahan, pengurangan, pembagian, dan perkalian.

Apakah mungkin melakukan operasi perkalian pada sebuah nilai dari tipe data string? Tentunya tidak, bukan? Untuk melakukan operasi aritmatika, kita membutuhkan nilai variabel dari tipe bilangan numerik, misalnya int. Oleh karena itu, mengkonversi tipe data dari string ke int harus dilakukan terlebih dahulu sebelum melakukan operasi aritmatika pada nilai-nilai variabel tersebut.

Satu hal lagi yang perlu diperhatikan pada saat melakukan konversi tipe data adalah ukuran dari masing-masing tipe data yang akan kita gunakan. Mengkonversi tipe data suatu variabel dari satu tipe data ke tipe data yang lain, tak hanya mengubah tipe datanya saja, namun juga ikut mengubah ukuran maksimum dari variabel tersebut.

Misalnya, tipe data int memiliki ukuran 4 byte. Artinya, tipe data int bisa menampung sebuah nilai numerik dari -2,147,483,648 sampai 2,147,483,647. Nilai numerik di luar rentang nilai tersebut tidak bisa ditampung oleh tipe data int.

Konversi antar tipe data bisa dilakukan dengan dua cara, yaitu secara implisit dan eksplisit.

Konversi Tipe Data Secara Implisit

Yang dimaksud dengan konversi secara implisit adalah ketika compiler mampu melakukan konversi tanpa perlu diberi instruksi apapun untuk melakukan konversi.

Tidak semua konversi bisa dilakukan secara implisit. C# hanya akan melakukan konversi secara implisit selama hal itu dimungkinkan.

Lalu, kondisi-kondisi seperti apa saja yang memungkinkan terjadinya konversi tipe data secara implisit?

1. konversi secara implisit dimungkinkan apabila tipe data yang akan dikonversi memiliki ukuran atau rentang nilai yang lebih kecil daripada tipe data hasil konversi.

Contohnya, tipe data int memiliki ukuran 4 Byte sedangkan tipe data double memiliki ukuran 8 Byte. Oleh karena itu tipe data int bisa dikonversi ke tipe data double secara implisit. Namun, tidak sebaliknya.

int variabelInt = 2147483647; 
double variabelDouble = variabelInt;

Pada potongan kode program di atas, compiler akan mengkonversi nilai variabel variabelInt yang bertipe data int secara implisit. Proses konversi implisit dari tipe data dengan ukuran yang lebih kecil ke tipe data dengan ukuran yang lebih besar biasa disebut dengan operasi pelebaran atau widening operation.

Sedangkan potongan kode program di bawah, akan menghasilkan eror yang menyatakan bahwa compiler tidak bisa melakukan konversi secara implisit dari double ke int.

double variabelDouble = 2147483647;
int variabelInt = variabelDouble;

Percobaan melakukan konversi implisit dari tipe data dengan ukuran yang lebih besar ke tipe data dengan ukuran yang lebih kecil seperti di atas biasa disebut dengan operasi penyempitan atau narrowing operation. Operasi penyempitan secara impisit akan selalu menghasilkan eror.

Konversi Antar Tipe Data - COmpiler tidak bisa melakukan konversi dari tipe double ke tipe int
Compiler Tidak Bisa Mengkonversi Tipe double Ke Tipe int Secara Implisit

2. konversi secara implisit hanya bisa dilakukan antar tipe data yang sepadan, misalnya sama-sama merupakan tipe bilangan numerik (double, int).

Tipe string dan tipe int bukan merupakan tipe data yang sepadan karena tipe string merupakan teks, sedangkan tipe int merupakan bilangan numerik. Oleh karena itu, compiler tidak bisa mengkonversi tipe data string menjadi int secara implisit. 

string variabelString = Console.ReadLine();
int variabelInt = variabelString;

Potongan kode program di atas akan menghasilkan eror seperti pada gambar di bawah ini.

Eror Yang Dihasilkan Ketika Anda Mencoba Mengkonversi Tipe string ke Tipe int Secara Implisit

Konversi Tipe Data Secara Eksplisit

Apabila kedua kondisi di mana konversi secara implisit dimungkinkan tidak terpenuhi, maka kita harus menggunakan konversi secara eksplisit. Konversi secara eksplisit ini biasa disebut dengan casting.

Di C#, casting bisa dilakukan dengan tiga cara, yaitu dengan menggunakan type modifier di depan variabel yang tipe datanya ingin diubah, menggunakan method yang disediakan oleh .NET di dalam class Convert, dan menggunakan method TryParse() atau Parse().

Perhatian: Method TryParse() dan Parse() hanya bisa digunakan untuk mengkonversi tipe string saja. Parsing sendiri berarti mengurai, artinya method tersebut akan mengurai sebuah teks/string karakter demi karakter dan kemudian mengkonversi karakter-karakter tersebut menjadi bilangan numerik atau boolean.

Menggunakan Pengubah Tipe (Type Modifier)

Untuk melakukan casting menggunakan pengubah tipe (type modifier), kita cukup menuliskan tipe data baru yang diinginkan, di depan variabel yang ingin kita ubah tipe datanya, dengan tanda kurung.

double varDouble = 1234.6;
int varInt;
// Mengkasting double ke int dengan cara menempatkan pengubah tipe (type modifier) tepat
// di depan tipe yang akan dikonversi, di dalam kurung.
varInt = (int)varDouble;

Nilai dari varInt adalah 1234. 

Menggunakan Method Dari Class Convert

Class Convert menyediakan beberapa method yang dapat digunakan untuk mengubah suatu tipe data ke tipe data yang lain seperti pada tabel di bawah ini.

METHOD DESKRIPSI
ToBoolean() Mengkonversi suatu nilai tertentu ke sebuah nilai boolean
ToByte() Mengkonversi suatu nilai tertentu ke sebuah nilai integer 8-bit
ToChar() Mengkonversi suatu nilai tertentu ke sebuah karakter unicode
ToDateTime() Mengkonversi suatu nilai tertentu ke sebuah nilai tanggal dan waktu
ToDecimal() Mengkonversi suatu nilai tertentu ke sebuah nilai desimal
ToDouble() Mengkonversi suatu nilai tertentu ke sebuah angka floating dengan presisi double
ToInt16() Mengkonversi suatu nilai tertentu ke sebuah nilai integer positif 16-bit
ToInt32() Mengkonversi suatu nilai tertentu ke sebuah nilai integer positif 32-bit
ToInt64() Mengkonversi suatu nilai tertentu ke sebuah nilai integer positif 64-bit
ToSByte() Mengkonversi suatu nilai tertentu ke sebuah nilai integer positif 8-bit
ToSingle() Mengkonversi suatu nilai tertentu ke sebuah angka floating dengan presisi single
ToUInt16() Mengkonversi suatu nilai tertentu ke sebuah nilai integer 16-bit
ToUInt32() Mengkonversi suatu nilai tertentu ke sebuah nilai integer 32-bit
ToUInt64() Mengkonversi suatu nilai tertentu ke sebuah nilai integer 64-bit

Potongan kode program di bawah ini mendemonstrasikan bagaimana menggunakan method dari class Convert untuk mengkonversi suatu nilai.

double varDouble = 1234.6;
int varInt;
// Mengkasting double ke int dengan menggunakan class Convert dan method ToInt32.
// Ini mengkonversi nilai double ke 32-bit signed integer.
varInt = Convert.ToInt32(varDouble);

Kali ini nilai dari varInt adalah 1235. 

Menggunakan Parse() dan TryParse()

Baik Parse() maupun TryParse() hanya bisa digunakan untuk mengkonversi nilai string ke nilai tipe tertentu (misal, numerik atau boolean). 

Potongan kode program di bawah ini mendemonstrasikan bagaimana menggunakan method Parse().

// mengkonversi string ke int
string intString = "12345";
int varInt = int.Parse(intString);

// mengkonversi string ke double
string doubleString = "12345.678";
double varDouble = double.Parse(doubleString);

// mengkonversi string ke boolean
string boolString = "true";
bool varBool = bool.Parse(boolString);

Kita bisa mengganti Parse() dengan TryParse() dan menghasilkan nilai konversi yang sama. Lalu apa bedanya? TryParse() akan menghasilkan nilai boolean false apabila gagal melakukan konversi. Sedangkan Parse() akan menghasilkan eksepsi apabila gagal melakukan konversi (aplikasi Anda biasanya akan mengalami crash apabila sebuah eksepsi tidak ditangani).

// mengkonversi string ke int dengan Parse()
string intString = "f12345";
int varInt = int.Parse(intString);

Kode program di atas akan menghasilkan eksepsi karena huruf f gagal dikonversi menjadi nilai integer.

Konversi tipe data - Parse() akan menghasilkan eksepsi ketika gagal melakukan konversi
Eksepsi Yang Dihasilkan Ketika Parse() Gagal Melakukan Konversi

Sekarang kita coba melakukan konversi dengan TryParse() untuk nilai input string yang sama. Kira-kira apa yang terjadi?

string intString = "f12345"; 
int varInt;

bool berhasilParsing = int.TryParse(intString, out varInt);

if (berhasilParsing) 
{ 
   Console.WriteLine(varInt); 
} 
else 
{ 
   Console.WriteLine("Parsing gagal");
}

Console.ReadLine();

Pertama-tama TryParse() akan mencoba mengkonversi nilai string yang tersimpan di variabel intString. Jika berhasil, TryParse() akan menghasilkan nilai boolean true dan hasil konversi dari nilai string ke int akan disimpan di dalam parameter out varInt. Jika gagal, TryParse() akan menghasilkan nilai boolean false. Nilai boolean tersebut kemudian disimpan di dalam variabel dari tipe bool bernama berhasilParsing.

Catatan: Kita akan mempelajari pengubah parameter out di materi “Pengubah Parameter Pada Method Di C#

Kemudian, jika berhasilParsing bernilai true (proses parsing berhasil), maka nilai varInt akan ditampilkan. Namun, jika berhasilParsing bernilai false, maka “Parsing gagal” akan ditampilkan di layar console.

Karena TryParse() gagal mengkonversi huruf f menjadi nilai integer, maka TryParse() akan menghasilkan nilai false. Sehingga yang ditampilkan di layar adalah seperti gambar berikut ini.

Konversi tipe data - tryparse() gagal melakukan konversi
Nilai Yang Ditampilkan Di Layar Jika Gagal Melakukan Konversi

Signed Overflow

Pada saat melakukan konversi tipe data, kita benar-benar perlu memperhatikan rentang nilai dari masing-masing tipe data yang terlibat dalam proses konversi.

Jika kita abai, meskipun proses konversi tidak menghasilkan eror, namun hasil yang kita dapatkan bisa saja di luar ekspektasi seperti pada contoh berikut ini.

short angka1 = 30000;
short angka2 = 30000;
// operator + mengkonversi operand ke tipe int secara implisit.
// Oleh krena itu, kita perlu mengkonversinya kembali ke tipe short secara eksplisit.
short jumlahShort = (short)(angka1 + angka2);
Console.WriteLine("jumlahShort = {0}", jumlahShort);

Ekspektasi kita, variabel jumlahShort mestinya bernilai 60000, bukan?

Kenyataannya , variabel jumlahShort di atas akan bernilai -5536. Hal ini sebenarnya tidak aneh karena tipe data short hanya bisa menampung nilai dengan rentang -32767~32767. Nilai 60000 jelas berada di luar rentang nilai tipe data short.

Tapi mengapa keluarannya bisa menghasilkan angka -5536?

Apabila kita menggunakan aplikasi kalkulator dengan mode programmer, angka 60000 nilainya sama dengan bilangan biner 1110 1010 0110 0000‬. Satu angka di dalam bilangan biner merepresentasikan 1 bit data. Jadi, bilangan biner 1110 1010 0110 0000‬ merepresentasikan 16 bit data. Tipe data short merupakan tipe data signed 16-bit. Signed berarti bahwa tipe data ini memiliki rentang nilai dari bilangan negatif sampai bilangan positif (-32767~32767).

signed overflow

Angka paling kiri pada bilangan biner dengan rentang negatif-positif merepresentasikan tanda (sign) positif atau negatif. Angka 1 merepresentasikan tanda minus (negatif) dan angka 0 merepresentasikan tanda plus (positif).

Untuk merubah bilangan biner di atas ke bilangan desimal, kita bisa melakukan perhitungan seperti berikut ini.

-2^15 + 2^14 + 2^13 + 2^11 + 2^9 + 2^6 + 2^5 = -32768 + 16384 + 8192 + 2048 + 512 + 64 + 32 = -5536
 

Bilangan pangkat di atas merepresentasikan posisi bit tiap-tiap data. Posisi bit paling kiri adalah 15 dan bit paling kanan adalah 0. Pada perhitungan di atas, kita hanya menghitung bit dengan nilai 1 saja karena nilai 0 dengan pangkat berapapun akan tetap bernilai 0. Angka 2 berarti bahwa tiap bit data merupakan bilangan biner (sistem bilangan yang hanya terdiri dari 2 angka, yaitu 0 dan 1). 

Karena bit paling kiri bernilai 1, maka kita perlu menambahkan tanda minus di depan angka 2. Jika semua bit kita jumlahkan, maka perhitungan di atas akan menghasilkan angka -5536.

Fenomena di atas biasa disebut dengan signed overflow, di mana nilai yang dihasilkan dari proses konversi pada tipe data dengan rentang negatif-positif melebihi daya tampung yang disediakan, dalam kata lain “meluap” atau overflowing.

Unsigned Overflow

Selain pada tipe signed seperti short, overflow juga bisa terjadi pada tipe unsigned seperti tipe byte. Tipe byte merupakan tipe data unsigned 8-bit. Unsigned berarti bahwa tipe ini memiliki rentang nilai pada bilangan positif saja. Ukuran 8-bit berarti bahwa tipe ini memiliki rentang nilai dari angka 0 sampai dengan 255.

Coba perhatikan baris kode program di bawah ini.

byte b1 = 100;
byte b2 = 250;
byte jml = (byte)(b1 + b2);
Console.WriteLine("jml = {0}", jml);

Kira-kira berapa nilai dari variabel jml yang ditampilkan ke layar console?

Mungkin Anda akan menjawab 350, tapi sayangnya jawaban tersebut tidak tepat.

Jangan kaget apabila nilai dari variabel jml adalah 94. Iya, bukan 350 melainkan 94.

Ingat bahwa tipe data byte hanya bisa menampung angka 0 sampai 255. Angka 350 jelas akan “meluap” karena daya tampung tipe byte terlalu kecil untuk menampung angka tersebut.

Lalu mengapa hasilnya menjadi 94?

Apabila Anda kembali menggunakan kalkulator dengan mode programming, angka 350 akan menghasilkan bilangan biner 0001 0101 1110. Angka biner yang dihasilkan berukuran 12-bit (bit ke-0 ~ bit ke-11).

Karena tipe byte hanya berukuran 8-bit, maka bit ke-8 sampai dengan bit ke-11 tidak bisa ditampung oleh tipe byte. Dengan demikian, hanya 8-bit paling kanan, yaitu 0101 1110, yang akan ditampung oleh tipe byte.

Apabila bilangan biner 0101 1110 kita konversi ke bilangan desimal, maka bilangan biner tersebut akan menghasilkan angka 94.

2^6 + 2^4 + 2^3 + 2^2 + 2^1 = 64 + 16 + 8 + 4 + 2 = 94

Fenomena di atas biasa disebut dengan unsigned overflow.

Menggunakan Ekspresi Checked

Mendapatkan keluaran di luar ekspektasi tentunya bukanlah sesuatu yang kita inginkan. Oleh karena itu kita membutuhkan sebuah mekanisme untuk memastikan bahwa proses konversi tidak terjadi overflow. Di C#, kita bisa menggunakan ekspresi checked.

Ekspresi ini akan mengecek apakah terjadi overflow pada suatu operasi konversi atau tidak. Jika terjadi overflow, ekspresi ini akan melontarkan sebuah eksepsi yang perlu kita tangani dengan blok try-catch seperti kode program di bawah ini.

try
{
    jml = checked((byte)(b1 + b2));
    Console.WriteLine("jml = {0}", jml);
}
catch (OverflowException ex)
{
    Console.WriteLine(ex.Message); // arithmetic operation resulted in an overflow
}

Pertama-tama, kode program di dalam blok try akan dieksekusi. Apabila terjadi overflow pada operasi (byte)(b1 + b2), maka ekspresi checked akan melontarkan sebuah eksepsi yang akan “ditangkap” atau ditangani oleh kode program di dalam blok catch.

Untuk saat ini, Anda tidak perlu khawatir dengan konstruksi try-catch di atas. Konstruksi ini akan kita pelajari bersama di dalam materi tentang bagaimana menangani sebuah ekspesi.

Penutup

Di C#, konversi tipe data dilakukan dengan dua cara, yaitu secara implisit dan eksplisit.

Untuk melakukan konversi tipe data secara eksplisit, kita bisa menggunakan type modifier, method dari class Convert, dan juga Parse() / TryParse().

Proses konversi secara eksplisit bisa menghasilkan nilai di luar ekspektasi apabila terjadi overflow. Kita bisa menggunakan ekspresi checked untuk memastikan bahwa hanya nilai yang sesuai dengan ekspektasi saja yang dihasilkan dan melontarkan eksepsi apabila terjadi overflow.

Itu saja materi kita kali ini. Jika Anda merasa kesulitan dalam memahami materi ini, jangan menyerah! Tulis kesulitan atau pertanyaan Anda di kolom komentar, saya akan membantu.

Selamat belajar!

Mendapat Manfaat Dari Tulisan Ini? Bantu Bagikan Ya...
Share on facebook
Facebook
Share on twitter
Twitter
Share on linkedin
LinkedIn
Share on whatsapp
WhatsApp
Tinggalkan Balasan

Close Menu