Improved speed of FastMath copysign methods.

JIRA: MATH-951

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1459887 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2013-03-22 16:25:17 +00:00
parent 787684869d
commit 5c14a29c69
4 changed files with 28 additions and 6 deletions

View File

@ -162,6 +162,9 @@
<contributor>
<name>Dan Checkoway</name>
</contributor>
<contributor>
<name>Charles Cooper</name>
</contributor>
<contributor>
<name>Paul Cowan</name>
</contributor>

View File

@ -55,6 +55,9 @@ This is a minor release: It combines bug fixes and new features.
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>

View File

@ -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

View File

@ -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);
}