You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2011/01/23 23:37:50 UTC

svn commit: r1062559 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/util/FastMath.java site/xdoc/changes.xml

Author: luc
Date: Sun Jan 23 22:37:50 2011
New Revision: 1062559

URL: http://svn.apache.org/viewvc?rev=1062559&view=rev
Log:
added FastMath.hypot
JIRA: MATH-478

Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/FastMath.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/FastMath.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/FastMath.java?rev=1062559&r1=1062558&r2=1062559&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/FastMath.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/FastMath.java Sun Jan 23 22:37:50 2011
@@ -3847,8 +3847,39 @@ public class FastMath {
      * @param y a value
      * @return sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
      */
-    public static double hypot(double x, double y) {
-        return StrictMath.hypot(x, y); // TODO provide our own implementation
+    public static double hypot(final double x, final double y) {
+        if (Double.isInfinite(x) || Double.isInfinite(y)) {
+            return Double.POSITIVE_INFINITY;
+        } else if (Double.isNaN(x) || Double.isNaN(y)) {
+            return Double.NaN;
+        } else {
+
+            final int expX = getExponent(x);
+            final int expY = getExponent(y);
+            if (expX > expY + 27) {
+                // y is neglectible with respect to x
+                return abs(x);
+            } else if (expY > expX + 27) {
+                // x is neglectible with respect to y
+                return abs(y);
+            } else {
+
+                // find an intermediate scale to avoid both overflow and underflow
+                final int middleExp = (expX + expY) / 2;
+
+                // scale parameters without losing precision
+                final double scaledX = scalb(x, -middleExp);
+                final double scaledY = scalb(y, -middleExp);
+
+                // compute scaled hypotenuse
+                final double scaledH = sqrt(scaledX * scaledX + scaledY * scaledY);
+
+                // remove scaling
+                return scalb(scaledH, middleExp);
+
+            }
+
+        }
     }
 
     /**

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=1062559&r1=1062558&r2=1062559&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sun Jan 23 22:37:50 2011
@@ -192,9 +192,9 @@ The <action> type attribute can be add,u
       </action>
       <action dev="luc" type="fix" issue="MATH-478">
           FastMath is not an exact replacement for StrictMath
-          (partially fixed) added nextAfter(double, double) and nextAfter(float,double)
-          (beware of the strange double second argument) so that they handle
-          special values in the way as StrictMath
+          (partially fixed) added hypot(double, double), nextAfter(double, double)
+          and nextAfter(float,double) (beware of the strange double second argument)
+          so that they handle special values in the way as StrictMath
       </action>
       <action dev="luc" type="fix" issue="MATH-497">
           FastMath is not an exact replacement for StrictMath