Improved speed of several FastMath methods.

Double.doubleToLongBits replaced with Double.doubleToRawLongBits at
several places.

JIRA: MATH-953

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1460587 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2013-03-25 10:19:51 +00:00
parent 724795b551
commit 1e6ad5c3ab
2 changed files with 24 additions and 19 deletions

View File

@ -55,7 +55,10 @@ This is a minor release: It combines bug fixes and new features.
Changes to existing features were made in a backwards-compatible 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. way such as to allow drop-in replacement of the v3.1[.1] JAR file.
"> ">
<action dev="luc" type="fix" issue="MATH-934"> <action dev="luc" type="update" issue="MATH-953" due-to="Charles Cooper">
Improved speed of several FastMath methods.
</action>
<action dev="luc" type="fix" issue="MATH-934">
Fixed Complex.reciprocal() for zero argument. Fixed Complex.reciprocal() for zero argument.
</action> </action>
<action dev="luc" type="update" issue="MATH-951" due-to="Charles Cooper"> <action dev="luc" type="update" issue="MATH-951" due-to="Charles Cooper">

View File

@ -365,7 +365,7 @@ public class FastMath {
if (d > -Precision.SAFE_MIN && d < Precision.SAFE_MIN){ if (d > -Precision.SAFE_MIN && d < Precision.SAFE_MIN){
return d; // These are un-normalised - don't try to convert return d; // These are un-normalised - don't try to convert
} }
long xl = Double.doubleToLongBits(d); long xl = Double.doubleToRawLongBits(d); // can take raw bits because just gonna convert it back
xl = xl & MASK_30BITS; // Drop low order bits xl = xl & MASK_30BITS; // Drop low order bits
return Double.longBitsToDouble(xl); return Double.longBitsToDouble(xl);
} }
@ -1130,7 +1130,7 @@ public class FastMath {
if (x==0) { // Handle special case of +0/-0 if (x==0) { // Handle special case of +0/-0
return Double.NEGATIVE_INFINITY; return Double.NEGATIVE_INFINITY;
} }
long bits = Double.doubleToLongBits(x); long bits = Double.doubleToRawLongBits(x);
/* Handle special cases of negative input, and NaN */ /* Handle special cases of negative input, and NaN */
if ((bits & 0x8000000000000000L) != 0 || x != x) { if ((bits & 0x8000000000000000L) != 0 || x != x) {
@ -1452,7 +1452,7 @@ public class FastMath {
if (x == 0) { if (x == 0) {
long bits = Double.doubleToLongBits(x); long bits = Double.doubleToRawLongBits(x);
if ((bits & 0x8000000000000000L) != 0) { if ((bits & 0x8000000000000000L) != 0) {
// -zero // -zero
long yi = (long) y; long yi = (long) y;
@ -2007,7 +2007,7 @@ public class FastMath {
private static void reducePayneHanek(double x, double result[]) private static void reducePayneHanek(double x, double result[])
{ {
/* Convert input double to bits */ /* Convert input double to bits */
long inbits = Double.doubleToLongBits(x); long inbits = Double.doubleToRawLongBits(x);
int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023; int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
/* Convert to fixed point representation */ /* Convert to fixed point representation */
@ -2237,7 +2237,7 @@ public class FastMath {
/* Check for zero and negative zero */ /* Check for zero and negative zero */
if (xa == 0.0) { if (xa == 0.0) {
long bits = Double.doubleToLongBits(x); long bits = Double.doubleToRawLongBits(x);
if (bits < 0) { if (bits < 0) {
return -0.0; return -0.0;
} }
@ -2356,7 +2356,7 @@ public class FastMath {
/* Check for zero and negative zero */ /* Check for zero and negative zero */
if (xa == 0.0) { if (xa == 0.0) {
long bits = Double.doubleToLongBits(x); long bits = Double.doubleToRawLongBits(x);
if (bits < 0) { if (bits < 0) {
return -0.0; return -0.0;
} }
@ -2857,7 +2857,7 @@ public class FastMath {
*/ */
public static double cbrt(double x) { public static double cbrt(double x) {
/* Convert input double to bits */ /* Convert input double to bits */
long inbits = Double.doubleToLongBits(x); long inbits = Double.doubleToRawLongBits(x);
int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023; int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
boolean subnormal = false; boolean subnormal = false;
@ -2869,7 +2869,7 @@ public class FastMath {
/* Subnormal, so normalize */ /* Subnormal, so normalize */
subnormal = true; subnormal = true;
x *= 1.8014398509481984E16; // 2^54 x *= 1.8014398509481984E16; // 2^54
inbits = Double.doubleToLongBits(x); inbits = Double.doubleToRawLongBits(x);
exponent = (int) ((inbits >> 52) & 0x7ff) - 1023; exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
} }
@ -3026,7 +3026,7 @@ public class FastMath {
if (Double.isInfinite(x)) { if (Double.isInfinite(x)) {
return Double.POSITIVE_INFINITY; return Double.POSITIVE_INFINITY;
} }
return abs(x - Double.longBitsToDouble(Double.doubleToLongBits(x) ^ 1)); return abs(x - Double.longBitsToDouble(Double.doubleToRawLongBits(x) ^ 1));
} }
/** /**
@ -3066,7 +3066,7 @@ public class FastMath {
} }
// decompose d // decompose d
final long bits = Double.doubleToLongBits(d); final long bits = Double.doubleToRawLongBits(d);
final long sign = bits & 0x8000000000000000L; final long sign = bits & 0x8000000000000000L;
int exponent = ((int) (bits >>> 52)) & 0x7ff; int exponent = ((int) (bits >>> 52)) & 0x7ff;
long mantissa = bits & 0x000fffffffffffffL; long mantissa = bits & 0x000fffffffffffffL;
@ -3254,8 +3254,8 @@ public class FastMath {
} }
// special cases MAX_VALUE to infinity and MIN_VALUE to 0 // special cases MAX_VALUE to infinity and MIN_VALUE to 0
// are handled just as normal numbers // are handled just as normal numbers
// can use raw bits since already dealt with infinity and NaN
final long bits = Double.doubleToLongBits(d); final long bits = Double.doubleToRawLongBits(d);
final long sign = bits & 0x8000000000000000L; final long sign = bits & 0x8000000000000000L;
if ((direction < d) ^ (sign == 0L)) { if ((direction < d) ^ (sign == 0L)) {
return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) + 1)); return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) + 1));
@ -3634,8 +3634,8 @@ public class FastMath {
// highest order bit of m and s is the same and one otherwise. // 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 // So (m^s) will be positive if both m and s have the same sign
// and negative otherwise. // and negative otherwise.
final long m = Double.doubleToLongBits(magnitude); final long m = Double.doubleToRawLongBits(magnitude); // don't care about NaN
final long s = Double.doubleToLongBits(sign); final long s = Double.doubleToRawLongBits(sign);
if ((m^s) >= 0) { if ((m^s) >= 0) {
return magnitude; return magnitude;
} }
@ -3655,8 +3655,8 @@ public class FastMath {
// highest order bit of m and s is the same and one otherwise. // 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 // So (m^s) will be positive if both m and s have the same sign
// and negative otherwise. // and negative otherwise.
final int m = Float.floatToIntBits(magnitude); final int m = Float.floatToRawIntBits(magnitude);
final int s = Float.floatToIntBits(sign); final int s = Float.floatToRawIntBits(sign);
if ((m^s) >= 0) { if ((m^s) >= 0) {
return magnitude; return magnitude;
} }
@ -3673,7 +3673,8 @@ public class FastMath {
* @return exponent for d in IEEE754 representation, without bias * @return exponent for d in IEEE754 representation, without bias
*/ */
public static int getExponent(final double d) { public static int getExponent(final double d) {
return (int) ((Double.doubleToLongBits(d) >>> 52) & 0x7ff) - 1023; // NaN and Infinite will return 1024 anywho so can use raw bits
return (int) ((Double.doubleToRawLongBits(d) >>> 52) & 0x7ff) - 1023;
} }
/** /**
@ -3686,7 +3687,8 @@ public class FastMath {
* @return exponent for d in IEEE754 representation, without bias * @return exponent for d in IEEE754 representation, without bias
*/ */
public static int getExponent(final float f) { public static int getExponent(final float f) {
return ((Float.floatToIntBits(f) >>> 23) & 0xff) - 127; // NaN and Infinite will return the same exponent anywho so can use raw bits
return ((Float.floatToRawIntBits(f) >>> 23) & 0xff) - 127;
} }
/** /**