Eğer kullanıyorsanız doubleveya float, sen yuvarlama kullanabilir veya bazı yuvarlama hataları görmek için beklemek gerekir. Bunu yapamazsanız kullanın BigDecimal.
Sahip olduğunuz problem, 0.1'in tam bir temsil olmaması ve hesaplamayı iki kez yaparak bu hatayı birleştiriyorsunuz.
Bununla birlikte, 100 doğru şekilde temsil edilebilir, bu yüzden şunu deneyin:
double x = 1234;
x /= 100;
System.out.println(x);
hangi yazdırır:
12.34
Bu işe yarıyor çünkü Double.toString(d)sizin adınıza az miktarda yuvarlama yapıyor, ancak çok fazla değil. Yuvarlamadan nasıl görünebileceğini merak ediyorsanız:
System.out.println(new BigDecimal(0.1));
System.out.println(new BigDecimal(x));
baskılar:
0.100000000000000005551115123125782702118158340454101562
12.339999999999999857891452847979962825775146484375
Kısacası, bunu açıkça yapsanız da yapmasanız da kayan noktada mantıklı yanıtlar için yuvarlama kaçınılmazdır.
Not: x / 100ve x * 0.01yuvarlama hatası söz konusu olduğunda tam olarak aynı değildir. Bunun nedeni, birinci ifadenin yuvarlama hatasının x değerlerine bağlı 0.01olması, ikincinin ise sabit bir yuvarlak hatasına sahip olmasıdır.
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);
}
baskılar
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