Thursday, April 24, 2008

Negative Zero and Java

The Wikipedia article on negative zero explains that negative zero is a computing-oriented concept rather than a mathematical concept. Because Java treats (positive) zero the same as negative zero in terms of equality comparisons, this concept of a negative zero and a positive zero is often not a problem.

The simple Java code below provides some tests of the negative and positive zero and their relationships in Java to one another.

public class NegativeZeroExample
public static void main(final String[] arguments)
final String negativeZeroString = "-0";
final String positiveZeroString = "+0";
final String zeroString = "0";

final double negativeZeroDouble = Double.parseDouble(negativeZeroString);
final double positiveZeroDouble = Double.parseDouble(positiveZeroString);
final double zeroDouble = Double.parseDouble(zeroString);

System.out.println("Zero : " + zeroDouble);
System.out.println("Positive Zero: " + positiveZeroDouble);
System.out.println("Negative Zero: " + negativeZeroDouble);

System.out.println("\nMath FUNCTIONS");
System.out.println( "Min(Zero, Negative Zero): "
+ Math.min(zeroDouble, negativeZeroDouble) );
System.out.println( "Min(Negative Zero,Positive Zero): "
+ Math.min(negativeZeroDouble, positiveZeroDouble) );
System.out.println( "Min(Zero,Positive Zero): "
+ Math.min(zeroDouble, positiveZeroDouble) + "\n" );

System.out.println( "Max(Zero, Negative Zero): "
+ Math.max(zeroDouble, negativeZeroDouble) );
System.out.println( "Max(Negative Zero,Positive Zero): "
+ Math.max(negativeZeroDouble, positiveZeroDouble) );
System.out.println( "Max(Zero,Positive Zero): "
+ Math.max(zeroDouble, positiveZeroDouble) + "\n" );

if ( positiveZeroDouble == negativeZeroDouble )
System.out.println("-0 is the same thing as +0\n");
System.out.println("-0 is NOT the same thing as +0\n");

if ( positiveZeroDouble > negativeZeroDouble )
System.out.println("+0 is greater than -0\n");
else if ( positiveZeroDouble < negativeZeroDouble )
System.out.println("+0 is less than -0\n");
System.out.println("+0 is neither less than nor greater than -0");

When the simple code above is compiled and run as shown in the following screen snapshot (click on it to see larger version), we see how Java treats (positive) zero and negative zero values. The equality operator (==) and the inequality operators (< and >) treat negative zero and (positive) zero exactly the same. However, the Math.min and Math.max functions treat (positive) zero and negative zero differently. While not shown in this code, StrictMath.min and StrictMath.max functions also treat (positive) zero as different than negative zero.

A highly useful tool for understanding the concept of negative zero and general issues surrounding the IEEE 754 floating point format is the web page and Java applet titled Inner Float: A Float Reveals Its Inner Nature. A much deeper treatise on floating point arithmetic is David Goldberg's What Every Computer Scientist Should Know About Floating Point Arithmetic.


Matt said...

Also, Double's equals() method differes from the semantics of double == comparison, so that Double(-0.0).equals(Double(0.0)) is false.

barelyserious said...

William Kahan (principal architect of the IEEE 754 standard) said this 10 years ago: How Java's Floating Point hurts Everyone Everywhere (pdf).