Category Archives: Reasoning

The mystery of negative zero (-0) in Java

Mathematically the number 0 does not have a sign, therefore -0, +0 and 0 are identical. We say that zero is neither positive nor negative. In computing numbers are stored in binary and there is concept of a sign bit. There is a bit in the binary representation, the sign bit, the content of which decides whether a number is negative or positive. The sign bit dictates the sign of the number (0 for positive and 1 for negative) and the remaining bits represent the magnitude of the number. There are various representation using which a particular implementation may store signed numbers but the concept of sign bit is essentially the same. Due to the way this representation works, for every number (that is the bits representing a certain magnitude) there are two representations one with sign bit equal to one and another with sign bit equal to zero. This applies to zero also and hence there is a +0 and there is a -0 !

The behavior of negative zero differs in case of integers (byte, short, int and long) and real numbers (float and double).

Let us explore this behavior with the help of some code snippets.

 Negative zero (-0) in case of integers

The behavior is similar in case of byte, short, int and long. However, I will use int in the following examples.

class NegativeZero{
    public static void main( String []args ){
        int negativeZero = -0;
        int positiveZero = +0;
        System.out.println( negativeZero == positiveZero );
        System.out.println( negativeZero > positiveZero );
        System.out.println( negativeZero < positiveZero );
        System.out.println( Math.min( negativeZero, positiveZero ) );
        System.out.println( Math.max( negativeZero, positiveZero ) );
        //System.out.println( 1/ positiveZero );
        //System.out.println( 1/ negativeZero );
    }
}

In the above code two integer variables had been declared to store negative zero (-0) and positive zero (+0). Line number 5 would display true indicating that both negative zero (-0) and positive zero (+0) are identical. Line number 6 and 7 would display false, also indicating that both negative zero (-0) and positive zero (+0) are identical. Line 8 and 9 would display 0 which indicates that internally negative zero (-0) and positive zero (+0) are identical. Line number 10 and 11 are commented as they would result in ArithmeticException because division by zero is indeterminate and is not allowed in mathematics.

Negative zero (-0) in case of real numbers

The behavior is similar in case of float and double. However, I will use float in the following examples.

class NegativeZero{
    public static void main( String []args ){
        float negativeZero = -0f;
        float positiveZero = +0f;
        System.out.println( negativeZero == positiveZero );
        System.out.println( negativeZero > positiveZero );
        System.out.println( negativeZero < positiveZero );
        System.out.println( Math.min( negativeZero, positiveZero ) );
        System.out.println( Math.max( negativeZero, positiveZero ) );
        System.out.println( 1/ positiveZero );
        System.out.println( 1/ negativeZero );
    }
}

In this above line number would display true implying that -0f and +0f are identical. Line number 6 and 7 would display false, also indicating that both negative zero (-0f) and positive zero (+0f) are identical. However, the max() and the min() functions of the Math class on line 8-9 would display -0.0 and 0.0 implying that -0f is less than 0.0f ! Line number 10 would display Infinity to indicate a very large quantity and line number 11 would display -Infinity to indicate a very small quantity.

Students can read What Every Computer Scientist Should Know About Floating-Point Arithmetic for details of representation of real numbers in Java.