Harus diakui, judul post kali ini tidak orisinil. Tetapi, judulnya tetap saja menarik dan mungkin post kali ini akan bisa menjelaskan tentang BigMistake ketika kita memakai BigDecimal.
1. BigMistake pertama dalam memakai BigDecimal dan BigInteger adalah : runtime!! No doubt about it. Salah satu pelajaran yang bisa dipetik dari BigMistake ini adalah : Gunakan BigDecimal dan BigInteger hanya jika diperlukan, sebisa mungkin gunakan double atau float. Tetapi, satu yang pasti, untuk perkara duit gunakan BigDecimal.
2. MathContext adalah wajib
Kode program berikut ini akan mengalikan 0.1 dengan 10. Hasil yang seharusnya keluar adalah 1. Tetapi, coba tebak output apa yang akan anda terima?
public static void main(String[] args) {
BigDecimal _ZeroPointOne = new BigDecimal(0.1);
System.out.println(_ZeroPointOne.multiply(BigDecimal.TEN));
}
Alih-alih mendapatkan output 1 atau 1.000 atau yang sejenis, anda akan memperoleh output 1.0000000000000000555111512312578270211815834045410156250.. mengejutkan…tentu saja.
Untuk mengatasi hal ini, Java sebenarnya sudah menyiapkan solusi, yaitu MathContext. Secara sederhana, MathContext adalah sebuah object yang menentukan setting-setting yang akan dipakai dalam kalkulasi, seperti presisi dan mode pembulatan.
Mari kita lihat output apa yang akan diterima jika kita menggunakan MathContext :
public static void main(String[] args) {
MathContext ctx = new MathContext(10, RoundingMode.HALF_UP);
BigDecimal _ZeroPointOne = new BigDecimal(0.1, ctx);
System.out.println(_ZeroPointOne.multiply(BigDecimal.TEN, ctx));
}
Yap.. ternyata hasil yang diperoleh adalah 1.000000000 .. hasil yang diharapkan tentunya.
Sekarang, apakah kita harus menyediakan sebuah MathContext dalam setiap operasi di BigDecimal. Sebaiknya iya dan sebaiknya MathContext yang dipakai dari awal sampai akhir penggunaan BigDecimal menggunakan context yang sama.
Agar tidak terlalu bingung mempelajari MathContext mungkin ada baiknya kita menggunakan MathContext standard yang sudah disediakan oleh Java. Ada empat buah MathContext yang sudah disediakan, yaitu UNLIMITED, DECIMAL32, DECIMAL64 dan DECIMAL128. Sebagai permulaan, gunakanlah MathContext.DECIMAL64
Lantas, bagaimana output yang akan kita peroleh dengan kode program di atas jika menggunakan MathContext DECIMAL64?
public static void main(String[] args) {
MathContext ctx = MathContext.DECIMAL64;
BigDecimal _ZeroPointOne = new BigDecimal(0.1, ctx);
System.out.println(_ZeroPointOne.multiply(BigDecimal.TEN, ctx));
}
Hore, kita mendapatkan output 1.000000000000000.. hasil yang diharapkan dengan jumlah angka di belakang koma yang cukup panjang.
Sebagai best practice, gunakan selalu MathContext dalam operasi-operasi perhitungan yang melibatkan BigDecimal dan untuk kebanyakan perhitungan, MathContext.DECIMAL64 sudah sangat mumpuni.