Index: src/test/org/apache/commons/lang/math/NumberUtilsTest.java
===================================================================
--- src/test/org/apache/commons/lang/math/NumberUtilsTest.java	(revision 607961)
+++ src/test/org/apache/commons/lang/math/NumberUtilsTest.java	(working copy)
@@ -1183,5 +1183,30 @@
         NumberUtils.createNumber("01l");
         NumberUtils.createNumber("1l");
     }
+
+    public void testLang381() {
+        assertEquals(1.2, NumberUtils.min(1.2, 2.5, Double.NaN), 0.01);
+        assertEquals(2.5, NumberUtils.max(1.2, 2.5, Double.NaN), 0.01);
+        assertTrue(Double.isNaN(NumberUtils.max(Double.NaN, Double.NaN, Double.NaN)));
+        assertEquals(1.2f, NumberUtils.min(1.2f, 2.5f, Float.NaN), 0.01);
+        assertEquals(2.5f, NumberUtils.max(1.2f, 2.5f, Float.NaN), 0.01);
+        assertTrue(Float.isNaN(NumberUtils.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, NumberUtils.max(a), 0.01);
+        assertEquals(1.2, NumberUtils.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, NumberUtils.max(b), 0.01);
+        assertEquals(1.2, NumberUtils.min(b), 0.01);
+
+        float[] aF = new float[] { 1.2f, Float.NaN, 3.7f, 27.0f, 42.0f, Float.NaN };
+        assertEquals(1.2f, NumberUtils.min(aF), 0.01);
+        assertEquals(42.0f, NumberUtils.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, NumberUtils.min(bF), 0.01);
+        assertEquals(42.0f, NumberUtils.max(bF), 0.01);
+    }
     
 }
Index: src/java/org/apache/commons/lang/math/NumberUtils.java
===================================================================
--- src/java/org/apache/commons/lang/math/NumberUtils.java	(revision 607961)
+++ src/java/org/apache/commons/lang/math/NumberUtils.java	(working copy)
@@ -795,9 +795,7 @@
         // Finds and returns min
         double min = array[0];
         for (int i = 1; i < array.length; i++) {
-            if (array[i] < min) {
-                min = array[i];
-            }
+            min = min(array[i], min);
         }
     
         return min;
@@ -822,9 +820,7 @@
         // Finds and returns min
         float min = array[0];
         for (int i = 1; i < array.length; i++) {
-            if (array[i] < min) {
-                min = array[i];
-            }
+            min = min(array[i], min);
         }
     
         return min;
@@ -959,9 +955,7 @@
         // Finds and returns max
         double max = array[0];
         for (int j = 1; j < array.length; j++) {
-            if (array[j] > max) {
-                max = array[j];
-            }
+            max = max(array[j], max);
         }
     
         return max;
@@ -986,9 +980,7 @@
         // Finds and returns max
         float max = array[0];
         for (int j = 1; j < array.length; j++) {
-            if (array[j] > max) {
-                max = array[j];
-            }
+            max = max(array[j], max);
         }
 
         return max;
@@ -1080,9 +1072,21 @@
      * @return  the smallest of the values
      */
     public static double min(double a, double b, double c) {
-        return Math.min(Math.min(a, b), c);
+        return min(min(a, b), c);
     }
 
+    // IEEE-754r
+    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>
      * 
@@ -1095,9 +1099,21 @@
      * @return  the smallest of the values
      */
     public static float min(float a, float b, float c) {
-        return Math.min(Math.min(a, b), c);
+        return min(min(a, b), c);
     }
 
+    // IEEE-754r
+    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);
+        }
+    }
+
     // 3 param max
     //-----------------------------------------------------------------------
     /**
@@ -1184,9 +1200,21 @@
      * @return  the largest of the values
      */
     public static double max(double a, double b, double c) {
-        return Math.max(Math.max(a, b), c);
+        return max(max(a, b), c);
     }
 
+    // IEEE-754r
+    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>
      * 
@@ -1199,9 +1227,21 @@
      * @return  the largest of the values
      */
     public static float max(float a, float b, float c) {
-        return Math.max(Math.max(a, b), c);
+        return max(max(a, b), c);
     }
 
+    // IEEE-754r
+    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);
+        }
+    }
+
     //-----------------------------------------------------------------------
     /**
      * <p>Compares two <code>doubles</code> for order.</p>
