Repository: commons-math Updated Branches: refs/heads/master 83c61da2c -> 0c0455fd6
Added a fast implementation of IEEEremainder in FastMath. Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/15a24dc0 Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/15a24dc0 Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/15a24dc0 Branch: refs/heads/master Commit: 15a24dc0fc9067fabe00857f8546aee4a5234a78 Parents: 83c61da Author: Luc Maisonobe <[email protected]> Authored: Sat May 16 14:22:46 2015 +0200 Committer: Luc Maisonobe <[email protected]> Committed: Sat May 16 14:24:13 2015 +0200 ---------------------------------------------------------------------- src/changes/changes.xml | 3 ++ .../org/apache/commons/math4/util/FastMath.java | 17 +++++++-- .../userguide/FastMathTestPerformance.java | 40 ++++++++++++++++++-- 3 files changed, 54 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-math/blob/15a24dc0/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 6afa831..1b448a8 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,9 @@ If the output is not quite correct, check for invisible trailing spaces! </release> <release version="4.0" date="XXXX-XX-XX" description=""> + <action dev="luc" type="add" > + Added a fast implementation of IEEEremainder in FastMath. + </action> <action dev="luc" type="fix" issue="MATH-1222" due-to="Benedikt Ritter"> Use Double.isNaN rather than x != x in FastMath. </action> http://git-wip-us.apache.org/repos/asf/commons-math/blob/15a24dc0/src/main/java/org/apache/commons/math4/util/FastMath.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/util/FastMath.java b/src/main/java/org/apache/commons/math4/util/FastMath.java index cd56192..3e96f69 100644 --- a/src/main/java/org/apache/commons/math4/util/FastMath.java +++ b/src/main/java/org/apache/commons/math4/util/FastMath.java @@ -3628,13 +3628,24 @@ public class FastMath { * <li>If the dividend is finite and the divisor is an infinity, the result equals the dividend.</li> * <li>If the dividend is a zero and the divisor is finite, the result equals the dividend.</li> * </ul> - * <p><b>Note:</b> this implementation currently delegates to {@link StrictMath#IEEEremainder} * @param dividend the number to be divided * @param divisor the number by which to divide * @return the remainder, rounded */ - public static double IEEEremainder(double dividend, double divisor) { - return StrictMath.IEEEremainder(dividend, divisor); // TODO provide our own implementation + public static double IEEEremainder(final double dividend, final double divisor) { + if (getExponent(dividend) == 1024 || getExponent(divisor) == 1024 || divisor == 0.0) { + // we are in one of the special cases + if (Double.isInfinite(divisor) && !Double.isInfinite(dividend)) { + return dividend; + } else { + return Double.NaN; + } + } else { + // we are in the general case + final double n = FastMath.rint(dividend / divisor); + final double remainder = Double.isInfinite(n) ? 0.0 : dividend - divisor * n; + return (remainder == 0) ? FastMath.copySign(remainder, dividend) : remainder; + } } /** Convert a long to interger, detecting overflows http://git-wip-us.apache.org/repos/asf/commons-math/blob/15a24dc0/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java ---------------------------------------------------------------------- diff --git a/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java b/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java index 8af6fca..697bd60 100644 --- a/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java +++ b/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java @@ -28,9 +28,9 @@ public class FastMathTestPerformance { private static final double F1 = 1d / RUNS; // Header format - private static final String FMT_HDR = "%-5s %13s %13s %13s Runs=%d Java %s (%s) %s (%s)"; + private static final String FMT_HDR = "%-13s %13s %13s %13s Runs=%d Java %s (%s) %s (%s)"; // Detail format - private static final String FMT_DTL = "%-5s %6d %6.1f %6d %6.4f %6d %6.4f"; + private static final String FMT_DTL = "%-13s %6d %6.1f %6d %6.4f %6d %6.4f"; public static void main(String[] args) { System.out.println(String.format(FMT_HDR, @@ -60,6 +60,7 @@ public class FastMathTestPerformance { testSqrt(); testTan(); testTanh(); + testIEEEremainder(); } @@ -429,7 +430,40 @@ public class FastMathTestPerformance { report("hypot",strictTime,fastTime,mathTime); assertTrue(!Double.isNaN(x)); } - + + private static void testIEEEremainder() { + double x = 0; + long time = System.nanoTime(); + int max = (int) FastMath.floor(FastMath.sqrt(RUNS)); + for (int i = 0; i < max; i++) { + for (int j = 0; j < max; j++) { + x += StrictMath.IEEEremainder((i - max/2) * (100.0 / max), (j + 1) * (100.0 / max)); + } + } + long strictTime = System.nanoTime() - time; + + x = 0; + time = System.nanoTime(); + for (int i = 0; i < max; i++) { + for (int j = 0; j < max; j++) { + x += FastMath.IEEEremainder((i - max/2) * (100.0 / max), (j + 1) * (100.0 / max)); + } + } + long fastTime = System.nanoTime() - time; + + x = 0; + time = System.nanoTime(); + for (int i = 0; i < max; i++) { + for (int j = 0; j < max; j++) { + x += Math.IEEEremainder((i - max/2) * (100.0 / max), (j + 1) * (100.0 / max)); + } + } + long mathTime = System.nanoTime() - time; + + report("IEEEremainder",strictTime,fastTime,mathTime); + assertTrue(!Double.isNaN(x)); + } + private static void testCbrt() { double x = 0; long time = System.nanoTime();
