Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Inaccuracy using double [duplicate]

Possible Duplicate:
Retain precision with Doubles in java
Strange floating-point behaviour in a Java program

I'm making a histogram class, and I'm encountering a weird issue.

Here are the basics of the class, there are more methods but they aren't relevant to the issue.

private int[] counters;
private int numCounters;
private double min, max, width;

public Histogram(double botRange, double topRange, int numCounters) {
    counters = new int[numCounters];
    this.numCounters = numCounters;
    min = botRange;
    max = topRange;
    width = (max - min) / (double) numCounters;
}

public void plotFrequency() {
    for (int i = 0; i < counters.length; i++) {
        writeLimit(i * width, (i + 1) * width);
        System.out.println(counters[i]);
    }
}

private void writeLimit(double start, double end) {
    System.out.print(start + " <= x < " + end + "\t\t");
}

the problem happens when I plot the frequencies. I've created 2 instances. new Histogram(0, 1, 10); new Histogram(0, 10, 10);

This is what they output.

Frequecy
0.0 <= x < 0.1      989
0.1 <= x < 0.2      1008
0.2 <= x < 0.30000000000000004      1007
0.30000000000000004 <= x < 0.4      1044
0.4 <= x < 0.5      981
0.5 <= x < 0.6000000000000001       997
0.6000000000000001 <= x < 0.7000000000000001        1005
0.7000000000000001 <= x < 0.8       988
0.8 <= x < 0.9      1003
0.9 <= x < 1.0      978

Frequecy
0.0 <= x < 1.0      990
1.0 <= x < 2.0      967
2.0 <= x < 3.0      1076
3.0 <= x < 4.0      1048
4.0 <= x < 5.0      971
5.0 <= x < 6.0      973
6.0 <= x < 7.0      1002
7.0 <= x < 8.0      988
8.0 <= x < 9.0      1003
9.0 <= x < 10.0     982    

So my question is, why am I getting the really long decimal limits in the first example, but not the second one?

like image 264
Marshall Brekka Avatar asked Oct 21 '11 22:10

Marshall Brekka


People also ask

Why is double not accurate in Java?

doubles are not exact. It is because there are infinite possible real numbers and only finite number of bits to represent these numbers.

How precise is a double in Java?

The double data type is a 64-bit double-precision IEEE 754 floating-point number. It means that it gives 15-16 decimal digits precision. It consumes more memory in comparison to the float data type. It is used to store decimal values.

Why float and double are not precise?

Floating-point decimal values generally do not have an exact binary representation. This is a side effect of how the CPU represents floating point data. For this reason, you may experience some loss of precision, and some floating-point operations may produce unexpected results.

What is the difference between float and double in Java?

Size: Float is of size 32 bits while double is of size 64 bits. Hence, double can handle much bigger fractional numbers than float. They differ in the allocation of bits for the representation of the number. Both float and double use 1 bit for representing the sign of the number.


2 Answers

doubles are not exact.

It is because there are infinite possible real numbers and only finite number of bits to represent these numbers.

have a look at: what every programmer should know about floating point arithmetic

like image 74
amit Avatar answered Oct 06 '22 03:10

amit


From The Floating-Point Guide:

Because internally, computers use a format (binary floating-point) that cannot accurately represent a number like 0.1, 0.2 or 0.3 at all.

When the code is compiled or interpreted, your “0.1” is already rounded to the nearest number in that format, which results in a small rounding error even before the calculation happens.

That accounts for your first example. The second one only involves integers, not fractions, and integers can be represented exactly in the binary floating-point format (up to 52 bits).

like image 27
Michael Borgwardt Avatar answered Oct 06 '22 02:10

Michael Borgwardt