java – Interesting issue with doubles

I am solving a Codeforces problem, and i ran into an interesting situation with doubles. When i add(d) to a HashSet the output is different from the output generated when i add(0.0) , although the value of d must be 0.0 since condition d == 0.0 must be true at the add operation. Why?

HashSet<Double> equations;

...

double d = (double)(y-y0)/(x-x0);
if(y == y0 && d == 0.0) {
    equations.add(0.0); // if add(d) the output is different
}

Problem link: http://codeforces.com/contest/514/problem/B

Code:

    int n;
    int c=0;
    int x0,y0;
    HashSet<Double> equations;

    Seqreader read = new Seqreader(" ");
    n=read.nextInt();
    x0 = read.nextInt();
    y0 = read.nextInt();
    equations = new HashSet<Double>();

    for(int i=0;i<n;i++){
        int x = read.nextInt();
        int y = read.nextInt();
        if (x == x0) {
            equations.add(20000.0);
        }else {
            double d = (double)(y-y0)/(x-x0);
            if(y == y0 && d == 0.0) {
                equations.add(0.0); // if add(d) output is different
            }
            else
                equations.add(d); // != 0
        }
    }
    System.out.println(equations.size());

Answer

-0.0 == 0.0, but Double.valueOf(-0.0) does not equal Double.valueOf(0.0).

In your first case, when calling equations.add(d), one time it is adding 0.0, and another it is adding -0.0, which adds two different Double values. In your second case, when you are calling equations.add(0.0) it is adding the same Double value twice.

A small test for this:

public static void main(String[] args) throws Exception {
    double pos = 0.0;
    System.out.println("" + (pos == 0.0)); // true
    double neg = -0.0;
    System.out.println("" + (neg == 0.0)); // true
    System.out.println("" + (neg == pos)); // true
    HashSet<Double> set = new HashSet<Double>();
    set.add(pos);
    set.add(neg);
    System.out.println("" + set.size()); // 2
}

Leave a Reply

Your email address will not be published. Required fields are marked *