Negative zero

10 views
Skip to first unread message

dei....@gmail.com

unread,
Nov 3, 2017, 4:17:45 PM11/3/17
to Jep Java Users
I am trying to evaluate a simple expression of a-b, where both values are a double data type, and they match each other. So I'm expecting to get zero as my result. But in a few instances I'm getting negative zero. Why is this? And is there a way I can fix it?

Richard Morris

unread,
Nov 3, 2017, 5:55:41 PM11/3/17
to Jep Java Users
This really is down to the underlying behaviour of the Java's Double type and the standard IEEE representation of double precision numbers. The IEEE rep has one bit for the sign and the other bits. You would find that some calculations in java will also give -0.0 as a result.

For the most part this does not matter. If you do comparison using == you find +0.0 == -0.0. If the Double.equals() method is used the 0.0 and -0.0 are treated as different numbers. 

If it is a big problem it possible to use an evaluator which checks if the result is negative zero and returns the positive zero if detected.

static class PosZeroEvaluator implements Evaluator {
    private static final long serialVersionUID = 1L;
    Evaluator rootEval;
    Double negativeZero = -0.0;
    Double positiveZero = 0.0;
    
    public PosZeroEvaluator(Evaluator rootEval) {
super();
this.rootEval = rootEval;
    }

    @Override
    public void init(Jep jep) {
rootEval.init(jep);
    }

    @Override
    public JepComponent getLightWeightInstance() {
return this;
    }

    @Override
    public Object evaluate(Node node) throws EvaluationException {
Object res = rootEval.evaluate(node);
if(res instanceof Double) {
    double dval = (Double) res;
    if(res.equals(negativeZero))
return positiveZero;
}
return res;
    }

    @Override
    public Object eval(Node node) throws EvaluationException {
return rootEval.eval(node);
    }
}

@Test
public void PosZeroTest() throws JepException {

            // first show standard behaviour

    String s = "0.0 * -1.0";
    jep.parse(s);
    Object res = jep.evaluate();
    System.out.println(res);
    assertEquals("-0.0",res.toString());

            // code to use the new evaluator
    jep.setComponent(new PosZeroEvaluator(new FastEvaluator()));
    jep.reinitializeComponents();

            // results using that evaluator     
    res = jep.evaluate();
    System.out.println(res);
    assertEquals("0.0",res.toString());
}



Reply all
Reply to author
Forward
0 new messages