commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject svn commit: r609475 - in /commons/proper/lang/trunk/src: java/org/apache/commons/lang/math/ test/org/apache/commons/lang/math/
Date Sun, 06 Jan 2008 23:59:01 GMT
Author: bayard
Date: Sun Jan  6 15:58:59 2008
New Revision: 609475

URL: http://svn.apache.org/viewvc?rev=609475&view=rev
Log:
Applying third patch from LANG-381. Fixes the minimum(float[]) type methods to correctly return
NaN when it is in the array, and adds an IEEE754rUtils class that obeys the IEEE 754r update
in which NaN in min/max methods should be ignored unless all values are NaN. 

Added:
    commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/IEEE754rUtils.java   (with
props)
    commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/IEEE754rUtilsTest.java
  (with props)
Modified:
    commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/NumberUtils.java
    commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/NumberUtilsTest.java

Added: commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/IEEE754rUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/IEEE754rUtils.java?rev=609475&view=auto
==============================================================================
--- commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/IEEE754rUtils.java (added)
+++ commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/IEEE754rUtils.java Sun
Jan  6 15:58:59 2008
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.math;
+
+/**
+ * <p>Provides IEEE-754r variants of NumberUtils methods. </p>
+ *
+ * <p>See: <a href="http://en.wikipedia.org/wiki/IEEE_754r">http://en.wikipedia.org/wiki/IEEE_754r</a></p>
+ *
+ * @since 2.4
+ * @version $Id: IEEE754rUtils.java 491076 2006-12-29 18:48:37Z bayard $
+ */
+public class IEEE754rUtils {
+    
+     /**
+     * <p>Returns the minimum value in an array.</p>
+     * 
+     * @param array  an array, must not be null or empty
+     * @return the minimum value in the array
+     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
+     * @throws IllegalArgumentException if <code>array</code> is empty
+     */
+    public static double min(double[] array) {
+        // Validates input
+        if (array == null) {
+            throw new IllegalArgumentException("The Array must not be null");
+        } else if (array.length == 0) {
+            throw new IllegalArgumentException("Array cannot be empty.");
+        }
+    
+        // Finds and returns min
+        double min = array[0];
+        for (int i = 1; i < array.length; i++) {
+            min = min(array[i], min);
+        }
+    
+        return min;
+    }
+
+    /**
+     * <p>Returns the minimum value in an array.</p>
+     * 
+     * @param array  an array, must not be null or empty
+     * @return the minimum value in the array
+     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
+     * @throws IllegalArgumentException if <code>array</code> is empty
+     */
+    public static float min(float[] array) {
+        // Validates input
+        if (array == null) {
+            throw new IllegalArgumentException("The Array must not be null");
+        } else if (array.length == 0) {
+            throw new IllegalArgumentException("Array cannot be empty.");
+        }
+    
+        // Finds and returns min
+        float min = array[0];
+        for (int i = 1; i < array.length; i++) {
+            min = min(array[i], min);
+        }
+    
+        return min;
+    }
+
+    /**
+     * <p>Gets the minimum of three <code>double</code> values.</p>
+     * 
+     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r. </p>
+     * 
+     * @param a  value 1
+     * @param b  value 2
+     * @param c  value 3
+     * @return  the smallest of the values
+     */
+    public static double min(double a, double b, double c) {
+        return min(min(a, b), c);
+    }
+
+    /**
+     * <p>Gets the minimum of two <code>double</code> values.</p>
+     * 
+     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r. </p>
+     * 
+     * @param a  value 1
+     * @param b  value 2
+     * @return  the smallest of the values
+     */
+    public static double min(double a, double b) {
+        if(Double.isNaN(a)) {
+            return b;
+        } else
+        if(Double.isNaN(b)) {
+            return a;
+        } else {
+            return Math.min(a, b);
+        }
+    }
+
+    /**
+     * <p>Gets the minimum of three <code>float</code> values.</p>
+     * 
+     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r. </p>
+     *
+     * @param a  value 1
+     * @param b  value 2
+     * @param c  value 3
+     * @return  the smallest of the values
+     */
+    public static float min(float a, float b, float c) {
+        return min(min(a, b), c);
+    }
+
+    /**
+     * <p>Gets the minimum of two <code>float</code> values.</p>
+     * 
+     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r. </p>
+     *
+     * @param a  value 1
+     * @param b  value 2
+     * @return  the smallest of the values
+     */
+    public static float min(float a, float b) {
+        if(Float.isNaN(a)) {
+            return b;
+        } else
+        if(Float.isNaN(b)) {
+            return a;
+        } else {
+            return Math.min(a, b);
+        }
+    }
+
+    /**
+     * <p>Returns the maximum value in an array.</p>
+     * 
+     * @param array  an array, must not be null or empty
+     * @return the minimum value in the array
+     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
+     * @throws IllegalArgumentException if <code>array</code> is empty
+     */
+    public static double max(double[] array) {
+        // Validates input
+        if (array== null) {
+            throw new IllegalArgumentException("The Array must not be null");
+        } else if (array.length == 0) {
+            throw new IllegalArgumentException("Array cannot be empty.");
+        }
+    
+        // Finds and returns max
+        double max = array[0];
+        for (int j = 1; j < array.length; j++) {
+            max = max(array[j], max);
+        }
+    
+        return max;
+    }
+
+    /**
+     * <p>Returns the maximum value in an array.</p>
+     * 
+     * @param array  an array, must not be null or empty
+     * @return the minimum value in the array
+     * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
+     * @throws IllegalArgumentException if <code>array</code> is empty
+     */
+    public static float max(float[] array) {
+        // Validates input
+        if (array == null) {
+            throw new IllegalArgumentException("The Array must not be null");
+        } else if (array.length == 0) {
+            throw new IllegalArgumentException("Array cannot be empty.");
+        }
+
+        // Finds and returns max
+        float max = array[0];
+        for (int j = 1; j < array.length; j++) {
+            max = max(array[j], max);
+        }
+
+        return max;
+    }
+     
+    /**
+     * <p>Gets the maximum of three <code>double</code> values.</p>
+     * 
+     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r. </p>
+     *
+     * @param a  value 1
+     * @param b  value 2
+     * @param c  value 3
+     * @return  the largest of the values
+     */
+    public static double max(double a, double b, double c) {
+        return max(max(a, b), c);
+    }
+
+    /**
+     * <p>Gets the maximum of two <code>double</code> values.</p>
+     * 
+     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r. </p>
+     *
+     * @param a  value 1
+     * @param b  value 2
+     * @return  the largest of the values
+     */
+    public static double max(double a, double b) {
+        if(Double.isNaN(a)) {
+            return b;
+        } else
+        if(Double.isNaN(b)) {
+            return a;
+        } else {
+            return Math.max(a, b);
+        }
+    }
+
+    /**
+     * <p>Gets the maximum of three <code>float</code> values.</p>
+     * 
+     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r. </p>
+     *
+     * @param a  value 1
+     * @param b  value 2
+     * @param c  value 3
+     * @return  the largest of the values
+     */
+    public static float max(float a, float b, float c) {
+        return max(max(a, b), c);
+    }
+
+    /**
+     * <p>Gets the maximum of two <code>float</code> values.</p>
+     * 
+     * <p>NaN is only returned if all numbers are NaN as per IEEE-754r. </p>
+     *
+     * @param a  value 1
+     * @param b  value 2
+     * @return  the largest of the values
+     */
+    public static float max(float a, float b) {
+        if(Float.isNaN(a)) {
+            return b;
+        } else
+        if(Float.isNaN(b)) {
+            return a;
+        } else {
+            return Math.max(a, b);
+        }
+    }
+
+}

Propchange: commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/IEEE754rUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/NumberUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/NumberUtils.java?rev=609475&r1=609474&r2=609475&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/NumberUtils.java (original)
+++ commons/proper/lang/trunk/src/java/org/apache/commons/lang/math/NumberUtils.java Sun Jan
 6 15:58:59 2008
@@ -783,6 +783,7 @@
      * @return the minimum value in the array
      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
      * @throws IllegalArgumentException if <code>array</code> is empty
+     * @see IEEE754rUtils#min(double[]) IEEE754rUtils for a version of this method that handles
NaN differently
      */
     public static double min(double[] array) {
         // Validates input
@@ -795,6 +796,9 @@
         // Finds and returns min
         double min = array[0];
         for (int i = 1; i < array.length; i++) {
+            if (Double.isNaN(array[i])) {
+                return Double.NaN;
+            }
             if (array[i] < min) {
                 min = array[i];
             }
@@ -810,6 +814,7 @@
      * @return the minimum value in the array
      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
      * @throws IllegalArgumentException if <code>array</code> is empty
+     * @see IEEE754rUtils#min(float[]) IEEE754rUtils for a version of this method that handles
NaN differently
      */
     public static float min(float[] array) {
         // Validates input
@@ -822,6 +827,9 @@
         // Finds and returns min
         float min = array[0];
         for (int i = 1; i < array.length; i++) {
+            if (Float.isNaN(array[i])) {
+                return Float.NaN;
+            }
             if (array[i] < min) {
                 min = array[i];
             }
@@ -947,6 +955,7 @@
      * @return the minimum value in the array
      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
      * @throws IllegalArgumentException if <code>array</code> is empty
+     * @see IEEE754rUtils#max(double[]) IEEE754rUtils for a version of this method that handles
NaN differently
      */
     public static double max(double[] array) {
         // Validates input
@@ -959,6 +968,9 @@
         // Finds and returns max
         double max = array[0];
         for (int j = 1; j < array.length; j++) {
+            if (Double.isNaN(array[j])) {
+                return Double.NaN;
+            }
             if (array[j] > max) {
                 max = array[j];
             }
@@ -974,6 +986,7 @@
      * @return the minimum value in the array
      * @throws IllegalArgumentException if <code>array</code> is <code>null</code>
      * @throws IllegalArgumentException if <code>array</code> is empty
+     * @see IEEE754rUtils#max(float[]) IEEE754rUtils for a version of this method that handles
NaN differently
      */
     public static float max(float[] array) {
         // Validates input
@@ -986,6 +999,9 @@
         // Finds and returns max
         float max = array[0];
         for (int j = 1; j < array.length; j++) {
+            if (Float.isNaN(array[j])) {
+                return Float.NaN;
+            }
             if (array[j] > max) {
                 max = array[j];
             }
@@ -1078,6 +1094,7 @@
      * @param b  value 2
      * @param c  value 3
      * @return  the smallest of the values
+     * @see IEEE754rUtils#min(double, double, double) for a version of this method that handles
NaN differently
      */
     public static double min(double a, double b, double c) {
         return Math.min(Math.min(a, b), c);
@@ -1093,6 +1110,7 @@
      * @param b  value 2
      * @param c  value 3
      * @return  the smallest of the values
+     * @see IEEE754rUtils#min(float, float, float) for a version of this method that handles
NaN differently
      */
     public static float min(float a, float b, float c) {
         return Math.min(Math.min(a, b), c);
@@ -1182,6 +1200,7 @@
      * @param b  value 2
      * @param c  value 3
      * @return  the largest of the values
+     * @see IEEE754rUtils#max(double, double, double) for a version of this method that handles
NaN differently
      */
     public static double max(double a, double b, double c) {
         return Math.max(Math.max(a, b), c);
@@ -1197,6 +1216,7 @@
      * @param b  value 2
      * @param c  value 3
      * @return  the largest of the values
+     * @see IEEE754rUtils#max(float, float, float) for a version of this method that handles
NaN differently
      */
     public static float max(float a, float b, float c) {
         return Math.max(Math.max(a, b), c);

Added: commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/IEEE754rUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/IEEE754rUtilsTest.java?rev=609475&view=auto
==============================================================================
--- commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/IEEE754rUtilsTest.java
(added)
+++ commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/IEEE754rUtilsTest.java
Sun Jan  6 15:58:59 2008
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang.math;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests {@link org.apache.commons.lang.math.IEEE754rUtils}.
+ *
+ * @version $Id: IEEE754rUtilsTest.java 583665 2007-10-11 01:34:13Z ggregory $
+ */
+public class IEEE754rUtilsTest extends TestCase {
+
+    public void testLang381() {
+        assertEquals(1.2, IEEE754rUtils.min(1.2, 2.5, Double.NaN), 0.01);
+        assertEquals(2.5, IEEE754rUtils.max(1.2, 2.5, Double.NaN), 0.01);
+        assertTrue(Double.isNaN(IEEE754rUtils.max(Double.NaN, Double.NaN, Double.NaN)));
+        assertEquals(1.2f, IEEE754rUtils.min(1.2f, 2.5f, Float.NaN), 0.01);
+        assertEquals(2.5f, IEEE754rUtils.max(1.2f, 2.5f, Float.NaN), 0.01);
+        assertTrue(Float.isNaN(IEEE754rUtils.max(Float.NaN, Float.NaN, Float.NaN)));
+
+        double[] a = new double[] { 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN };
+        assertEquals(42.0, IEEE754rUtils.max(a), 0.01);
+        assertEquals(1.2, IEEE754rUtils.min(a), 0.01);
+
+        double[] b = new double[] { Double.NaN, 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN
};
+        assertEquals(42.0, IEEE754rUtils.max(b), 0.01);
+        assertEquals(1.2, IEEE754rUtils.min(b), 0.01);
+
+        float[] aF = new float[] { 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN };
+        assertEquals(1.2f, IEEE754rUtils.min(aF), 0.01);
+        assertEquals(42.0f, IEEE754rUtils.max(aF), 0.01);
+
+        float[] bF = new float[] { Float.NaN, 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN
};
+        assertEquals(1.2f, IEEE754rUtils.min(bF), 0.01);
+        assertEquals(42.0f, IEEE754rUtils.max(bF), 0.01);
+    }
+    
+}

Propchange: commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/IEEE754rUtilsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/NumberUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/NumberUtilsTest.java?rev=609475&r1=609474&r2=609475&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/NumberUtilsTest.java (original)
+++ commons/proper/lang/trunk/src/test/org/apache/commons/lang/math/NumberUtilsTest.java Sun
Jan  6 15:58:59 2008
@@ -1183,5 +1183,26 @@
         NumberUtils.createNumber("01l");
         NumberUtils.createNumber("1l");
     }
+
+    public void testLang381() {
+        assertTrue(Double.isNaN(NumberUtils.min(1.2, 2.5, Double.NaN)));
+        assertTrue(Double.isNaN(NumberUtils.max(1.2, 2.5, Double.NaN)));
+        assertTrue(Float.isNaN(NumberUtils.min(1.2f, 2.5f, Float.NaN)));
+        assertTrue(Float.isNaN(NumberUtils.max(1.2f, 2.5f, Float.NaN)));
+
+        double[] a = new double[] { 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN };
+        assertTrue(Double.isNaN(NumberUtils.max(a)));
+        assertTrue(Double.isNaN(NumberUtils.min(a)));
+
+        double[] b = new double[] { Double.NaN, 1.2, Double.NaN, 3.7, 27.0, 42.0, Double.NaN
};
+        assertTrue(Double.isNaN(NumberUtils.max(b)));
+        assertTrue(Double.isNaN(NumberUtils.min(b)));
+
+        float[] aF = new float[] { 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN };
+        assertTrue(Float.isNaN(NumberUtils.max(aF)));
+
+        float[] bF = new float[] { Float.NaN, 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN
};
+        assertTrue(Float.isNaN(NumberUtils.max(bF)));
+    }
     
 }



Mime
View raw message