Here is a patch for the bugs in java.lang.Math.{max,min}, along with some
speed optimizations for abs.
--
Eric Blake, Elixent, Castlemead, Lwr Castle St., Bristol BS1 3AG, UK
[EMAIL PROTECTED] tel:+44(0)117 917 5611
2001-08-10 Eric Blake <[EMAIL PROTECTED]>
* java/lang/Math.java (abs): optimize
(min, max): fix bugs
Index: java/lang/Math.java
===================================================================
RCS file: /cvs/classpath/java/lang/Math.java,v
retrieving revision 1.6
diff -u -r1.6 Math.java
--- java/lang/Math.java 2000/03/16 23:31:30 1.6
+++ java/lang/Math.java 2001/08/10 09:41:27
@@ -1,5 +1,5 @@
/* java.lang.Math
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2001 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,7 @@
*
* @author Paul Fisher
* @author John Keiser
+ * @author Eric Blake <[EMAIL PROTECTED]>
* @since JDK1.1
*/
public final class Math {
@@ -105,7 +106,9 @@
* @return the absolute value.
*/
public static float abs(float a) {
- return Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a));
+ // avoid method call overhead, but treat -0.0 correctly
+ // return Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a));
+ return (a == 0) ? 0 : (a < 0) ? -a : a;
}
/**
@@ -115,7 +118,9 @@
* @return the absolute value.
*/
public static double abs(double a) {
- return Double.longBitsToDouble((Double.doubleToLongBits(a) << 1) >>>
1);
+ // avoid method call overhead, but treat -0.0 correctly
+ // return Double.longBitsToDouble((Double.doubleToLongBits(a) << 1) >>>
1);
+ return (a == 0) ? 0 : (a < 0) ? -a : a;
}
/**
@@ -139,26 +144,38 @@
}
/**
- * Return whichever argument is smaller.
+ * Return whichever argument is smaller. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, -0 is always smaller.
* @param a the first number
* @param b a second number
* @return the smaller of the two numbers.
*/
public static float min(float a, float b) {
- if (a == 0.0f && b == 0.0f) // return -0.0f, if a or b is -0.0f
- return ((Float.floatToIntBits(a) >> 31) == 1) ? a : b;
+ if (Float.isNaN(a))
+ return a;
+ if (Float.isNaN(b))
+ return b;
+ // recall that -0.0 == 0.0, -0.0*0.0 is -0.0, 1/[+-]0 is [+-]Infinity
+ if (a == 0 && b == 0)
+ return (1 / (a * b) == Float.POSITIVE_INFINITY) ? a : -0.0f;
return (a < b) ? a : b;
}
/**
- * Return whichever argument is smaller.
+ * Return whichever argument is smaller. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, -0 is always smaller.
* @param a the first number
* @param b a second number
* @return the smaller of the two numbers.
*/
public static double min(double a, double b) {
- if (a == 0.0d && b == 0.0d) // return -0.0d, if a or b is -0.0d
- return ((Double.doubleToLongBits(a) >> 63) == 1) ? a : b;
+ if (Double.isNaN(a))
+ return a;
+ if (Double.isNaN(b))
+ return b;
+ // recall that -0.0 == 0.0, -0.0*0.0 is -0.0, 1/[+-]0 is [+-]Infinity
+ if (a == 0 && b == 0)
+ return (1 / (a * b) == Double.POSITIVE_INFINITY) ? a : -0.0;
return (a < b) ? a : b;
}
@@ -183,26 +200,38 @@
}
/**
- * Return whichever argument is larger.
+ * Return whichever argument is larger. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, 0 is always larger.
* @param a the first number
* @param b a second number
* @return the larger of the two numbers.
*/
public static float max(float a, float b) {
- if (a == 0.0f && b == 0.0f) // return +0.0f, if a or b is +0.0f
- return ((Float.floatToIntBits(a) >> 31) == 0) ? a : b;
+ if (Float.isNaN(a))
+ return a;
+ if (Float.isNaN(b))
+ return b;
+ // recall that -0.0 == 0.0, -0.0*0.0 is -0.0, 1/[+-]0 is [+-]Infinity
+ if (a == 0 && b == 0)
+ return (1 / (a * b) == Float.POSITIVE_INFINITY) ? a : 0.0f;
return (a > b) ? a : b;
}
/**
- * Return whichever argument is larger.
+ * Return whichever argument is larger. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, 0 is always larger.
* @param a the first number
* @param b a second number
* @return the larger of the two numbers.
*/
public static double max(double a, double b) {
- if (a == 0.0d && b == 0.0d) // return +0.0d, if a or b is +0.0d
- return ((Double.doubleToLongBits(a) >> 63) == 0) ? a : b;
+ if (Double.isNaN(a))
+ return a;
+ if (Double.isNaN(b))
+ return b;
+ // recall that -0.0 == 0.0, -0.0*0.0 is -0.0, 1/[+-]0 is [+-]Infinity
+ if (a == 0 && b == 0)
+ return (1 / (a * b) == Double.POSITIVE_INFINITY) ? a : 0.0;
return (a > b) ? a : b;
}
_______________________________________________
Classpath mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/classpath