[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Math.min
From: |
John Keiser |
Subject: |
Re: Math.min |
Date: |
18 Aug 2001 14:02:03 -0400 |
This patch looks fine to me, but as I don't have Classpath running right
now (and won't for a bit until I get done hacking Mozilla) I can't test
them. Therefore it is on the patches list now, at
https://savannah.gnu.org/patch/?group_id=85.
If someone could run this against the Muave tests right quick (John
Leuner perhaps?) that would be wonderful :)
--John
On 10 Aug 2001 10:44:16 +0100, Eric Blake wrote:
> 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
> address@hidden tel:+44(0)117 917 5611
>
> 2001-08-10 Eric Blake <address@hidden>
>
> * 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 <address@hidden>
> * @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
> address@hidden
> http://mail.gnu.org/mailman/listinfo/classpath