Peter Dickerson wrote: > > Math.min(float,float) seems to have incorrect behaviour for negative zero. >
You must have a stale file. I show CVS to have this already (which avoids a method call, and does not have the bug you mentioned): public static float min (float a, float b) { // this check for NaN, from JLS 15.21.1, saves a method call if (a != a) return a; // no need to check if b is NaN; < will work correctly // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special if (a == 0 && b == 0) return -(-a - b); return (a < b) ? a : b; } However, I did notice some similar problems in Double and Float, and am checking in the following patch. -- This signature intentionally left boring. Eric Blake [EMAIL PROTECTED] BYU student, free software programmer
2002-01-15 Eric Blake <[EMAIL PROTECTED]> * java/lang/Double.java (equals, compare): Fix 0.0 vs. -0.0 math. * java/lang/Float.java (equals, compare): Ditto. Index: java/lang/Double.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/lang/Double.java,v retrieving revision 1.26 diff -u -r1.26 Double.java --- java/lang/Double.java 15 Nov 2001 02:23:35 -0000 1.26 +++ java/lang/Double.java 15 Jan 2002 16:34:04 -0000 @@ -1,5 +1,5 @@ /* Double.java -- object wrapper for double primitive - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,7 +44,8 @@ * * @author Paul Fisher * @author Andrew Haley <[EMAIL PROTECTED]> - * @since JDK 1.0 + * @author Eric Blake <[EMAIL PROTECTED]> + * @since 1.0 */ public final class Double extends Number implements Comparable { @@ -163,9 +164,12 @@ if (!(obj instanceof Double)) return false; - Double d = (Double) obj; + double d = ((Double) obj).value; - return doubleToLongBits (value) == doubleToLongBits (d.doubleValue ()); + // common case first, then check NaN and 0 + if (value == d) + return (value != 0) || (1 / value == 1 / d); + return isNaN(value) && isNaN(d); } /** @@ -336,10 +340,9 @@ return isNaN (y) ? 0 : 1; if (isNaN (y)) return -1; - if (x == 0.0d && y == -0.0d) - return 1; - if (x == -0.0d && y == 0.0d) - return -1; + // recall that 0.0 == -0.0, so we convert to infinites and try again + if (x == 0 && y == 0) + return (int) (1 / x - 1 / y); if (x == y) return 0; Index: java/lang/Float.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/lang/Float.java,v retrieving revision 1.21 diff -u -r1.21 Float.java --- java/lang/Float.java 11 Nov 2001 16:07:09 -0000 1.21 +++ java/lang/Float.java 15 Jan 2002 16:34:04 -0000 @@ -1,5 +1,5 @@ /* java.lang.Float - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,7 +44,8 @@ * * @author Paul Fisher * @author Andrew Haley <[EMAIL PROTECTED]> - * @since JDK 1.0 + * @author Eric Blake <[EMAIL PROTECTED]> + * @since 1.0 */ public final class Float extends Number implements Comparable { @@ -232,9 +233,12 @@ if (!(obj instanceof Float)) return false; - Float f = (Float) obj; + float f = ((Float) obj).value; - return floatToIntBits (value) == floatToIntBits (f.floatValue ()); + // common case first, then check NaN and 0 + if (value == f) + return (value != 0) || (1 / value == 1 / f); + return isNaN(value) && isNaN(f); } /** @@ -484,10 +488,9 @@ return isNaN (y) ? 0 : 1; if (isNaN (y)) return -1; - if (x == 0.0 && y == -0.0) - return 1; - if (x == -0.0 && y == 0.0) - return -1; + // recall that 0.0 == -0.0, so we convert to infinities and try again + if (x == 0 && y == 0) + return (int) (1 / x - 1 / y); if (x == y) return 0;