Jika Anda menggunakan doubleatau float, Anda harus menggunakan pembulatan atau akan melihat beberapa kesalahan pembulatan. Jika Anda tidak dapat melakukan ini, gunakan BigDecimal.
Masalah yang Anda hadapi adalah bahwa 0,1 bukanlah representasi yang tepat, dan dengan melakukan kalkulasi dua kali, Anda menambah kesalahan itu.
Namun, 100 dapat direpresentasikan secara akurat, jadi cobalah:
double x = 1234;
x /= 100;
System.out.println(x);
yang mencetak:
12.34
Ini berfungsi karena Double.toString(d)melakukan sejumlah kecil pembulatan atas nama Anda, tetapi tidak banyak. Jika Anda bertanya-tanya bagaimana tampilannya tanpa pembulatan:
System.out.println(new BigDecimal(0.1));
System.out.println(new BigDecimal(x));
cetakan:
0.100000000000000005551115123125782702118158340454101562
12.339999999999999857891452847979962825775146484375
Singkatnya, pembulatan tidak dapat dihindari untuk jawaban yang masuk akal dalam floating point apakah Anda melakukannya secara eksplisit atau tidak.
Catatan: x / 100dan x * 0.01tidak persis sama dalam hal kesalahan pembulatan. Ini karena kesalahan putaran untuk ekspresi pertama bergantung pada nilai x, sedangkan 0.01kesalahan putaran kedua memiliki kesalahan putaran tetap.
for(int i=0;i<200;i++) {
double d1 = (double) i / 100;
double d2 = i * 0.01;
if (d1 != d2)
System.out.println(d1 + " != "+d2);
}
cetakan
0.35 != 0.35000000000000003
0.41 != 0.41000000000000003
0.47 != 0.47000000000000003
0.57 != 0.5700000000000001
0.69 != 0.6900000000000001
0.7 != 0.7000000000000001
0.82 != 0.8200000000000001
0.83 != 0.8300000000000001
0.94 != 0.9400000000000001
0.95 != 0.9500000000000001
1.13 != 1.1300000000000001
1.14 != 1.1400000000000001
1.15 != 1.1500000000000001
1.38 != 1.3800000000000001
1.39 != 1.3900000000000001
1.4 != 1.4000000000000001
1.63 != 1.6300000000000001
1.64 != 1.6400000000000001
1.65 != 1.6500000000000001
1.66 != 1.6600000000000001
1.88 != 1.8800000000000001
1.89 != 1.8900000000000001
1.9 != 1.9000000000000001
1.91 != 1.9100000000000001