classpath
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]