Author: luc
Date: Fri Mar 22 16:25:17 2013
New Revision: 1459887

URL: http://svn.apache.org/r1459887
Log:
Improved speed of FastMath copysign methods.

JIRA: MATH-951

Modified:
    commons/proper/math/trunk/pom.xml
    commons/proper/math/trunk/src/changes/changes.xml
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java
    
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java

Modified: commons/proper/math/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/pom.xml?rev=1459887&r1=1459886&r2=1459887&view=diff
==============================================================================
--- commons/proper/math/trunk/pom.xml (original)
+++ commons/proper/math/trunk/pom.xml Fri Mar 22 16:25:17 2013
@@ -163,6 +163,9 @@
       <name>Dan Checkoway</name>
     </contributor>
     <contributor>
+      <name>Charles Cooper</name>
+    </contributor>
+    <contributor>
       <name>Paul Cowan</name>
     </contributor>
     <contributor>

Modified: commons/proper/math/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1459887&r1=1459886&r2=1459887&view=diff
==============================================================================
--- commons/proper/math/trunk/src/changes/changes.xml (original)
+++ commons/proper/math/trunk/src/changes/changes.xml Fri Mar 22 16:25:17 2013
@@ -55,6 +55,9 @@ This is a minor release: It combines bug
   Changes to existing features were made in a backwards-compatible
   way such as to allow drop-in replacement of the v3.1[.1] JAR file.
 ">
+      <action dev="luc" type="update" issue="MATH-951" due-to="Charles Cooper">
+        Improved speed of FastMath copysign methods.
+      </action>
       <action dev="erans" type="add" issue="MATH-817" due-to="Jared Becksfort">
         Added Multivariate Normal Mixture Model Fitting by Expectation 
Maximization.
       </action>

Modified: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java?rev=1459887&r1=1459886&r2=1459887&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java
 Fri Mar 22 16:25:17 2013
@@ -3630,9 +3630,13 @@ public class FastMath {
      * @return the magnitude with the same sign as the {@code sign} argument
      */
     public static double copySign(double magnitude, double sign){
-        long m = Double.doubleToLongBits(magnitude);
-        long s = Double.doubleToLongBits(sign);
-        if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK
+        // The highest order bit is going to be zero if the
+        // highest order bit of m and s is the same and one otherwise.
+        // So (m^s) will be positive if both m and s have the same sign
+        // and negative otherwise.
+        final long m = Double.doubleToLongBits(magnitude);
+        final long s = Double.doubleToLongBits(sign);
+        if ((m^s) >= 0) {
             return magnitude;
         }
         return -magnitude; // flip sign
@@ -3647,9 +3651,13 @@ public class FastMath {
      * @return the magnitude with the same sign as the {@code sign} argument
      */
     public static float copySign(float magnitude, float sign){
-        int m = Float.floatToIntBits(magnitude);
-        int s = Float.floatToIntBits(sign);
-        if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK
+        // The highest order bit is going to be zero if the
+        // highest order bit of m and s is the same and one otherwise.
+        // So (m^s) will be positive if both m and s have the same sign
+        // and negative otherwise.
+        final int m = Float.floatToIntBits(magnitude);
+        final int s = Float.floatToIntBits(sign);
+        if ((m^s) >= 0) {
             return magnitude;
         }
         return -magnitude; // flip sign

Modified: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java?rev=1459887&r1=1459886&r2=1459887&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java
 (original)
+++ 
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/FastMathTest.java
 Fri Mar 22 16:25:17 2013
@@ -1149,6 +1149,10 @@ public class FastMathTest {
         double delta = 0.0;
         Assert.assertEquals(1.0, FastMath.copySign(1d, 2.0), delta);
         Assert.assertEquals(1.0, FastMath.copySign(1d, 0.0), delta);
+        Assert.assertEquals(-1.0, FastMath.copySign(1d, -0.0), delta);
+        Assert.assertEquals(1.0, FastMath.copySign(1d, 
Double.POSITIVE_INFINITY), delta);
+        Assert.assertEquals(-1.0, FastMath.copySign(1d, 
Double.NEGATIVE_INFINITY), delta);
+        Assert.assertEquals(1.0, FastMath.copySign(1d, Double.NaN), delta);
         Assert.assertEquals(-1.0, FastMath.copySign(1d, -2.0), delta);
     }
 
@@ -1157,6 +1161,10 @@ public class FastMathTest {
         float delta = 0.0F;
         Assert.assertEquals(1.0F, FastMath.copySign(1d, 2.0F), delta);
         Assert.assertEquals(1.0F, FastMath.copySign(1d, 0.0F), delta);
+        Assert.assertEquals(-1.0F, FastMath.copySign(1d, -0.0F), delta);
+        Assert.assertEquals(1.0F, FastMath.copySign(1d, 
Float.POSITIVE_INFINITY), delta);
+        Assert.assertEquals(-1.0F, FastMath.copySign(1d, 
Float.NEGATIVE_INFINITY), delta);
+        Assert.assertEquals(1.0F, FastMath.copySign(1d, Float.NaN), delta);
         Assert.assertEquals(-1.0F, FastMath.copySign(1d, -2.0F), delta);
     }
 


Reply via email to