You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sebb <se...@gmail.com> on 2014/10/07 23:40:31 UTC

Re: git commit: Added all Java 8 StrictMath methods to FastMath.

On 7 October 2014 12:55,  <lu...@apache.org> wrote:
> Repository: commons-math
> Updated Branches:
>   refs/heads/master cee04d164 -> a67f0a33e
>
>
> Added all Java 8 StrictMath methods to FastMath.
>
> This change allows FastMath to remain compatible with newer Java
> versions, despite it stiil requires only Java 5 to compile and run.
>
> JIRA: MATH-1156
>
>
> Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
> Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/a67f0a33
> Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/a67f0a33
> Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/a67f0a33
>
> Branch: refs/heads/master
> Commit: a67f0a33e68abf1c985db28b19ce70f427fd48bd
> Parents: cee04d1
> Author: Luc Maisonobe <lu...@apache.org>
> Authored: Tue Oct 7 13:54:55 2014 +0200
> Committer: Luc Maisonobe <lu...@apache.org>
> Committed: Tue Oct 7 13:54:55 2014 +0200
>
> ----------------------------------------------------------------------
>  pom.xml                                         |   6 +-
>  src/changes/changes.xml                         |   4 +
>  .../math3/exception/util/LocalizedFormats.java  |   1 +
>  .../org/apache/commons/math3/util/FastMath.java | 334 +++++++++++++++
>  .../util/LocalizedFormats_fr.properties         |   1 +
>  .../exception/util/LocalizedFormatsTest.java    |   3 +-
>  .../apache/commons/math3/util/FastMathTest.java | 429 ++++++++++++++++++-
>  7 files changed, 769 insertions(+), 9 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/pom.xml
> ----------------------------------------------------------------------
> diff --git a/pom.xml b/pom.xml
> index 3ca4958..3a62e60 100644
> --- a/pom.xml
> +++ b/pom.xml
> @@ -38,9 +38,9 @@
>    </issueManagement>
>
>    <scm>
> -    <connection>scm:svn:http://svn.apache.org/repos/asf/commons/proper/math/trunk</connection>
> -    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/commons/proper/math/trunk</developerConnection>
> -    <url>http://svn.apache.org/viewvc/commons/proper/math/trunk</url>
> +    <connection>scm:git:http://git-wip-us.apache.org/repos/asf/commons-math.git</connection>
> +    <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/commons-math.git</developerConnection>
> +    <url>https://git-wip-us.apache.org/repos/asf?p=commons-math.git</url>
>    </scm>

The pom.xml change appears to belong to a different commit; it does
not seem to relate to the log message.

>    <distributionManagement>
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/changes/changes.xml
> ----------------------------------------------------------------------
> diff --git a/src/changes/changes.xml b/src/changes/changes.xml
> index 0c6520b..7ea96c9 100644
> --- a/src/changes/changes.xml
> +++ b/src/changes/changes.xml
> @@ -73,6 +73,10 @@ Users are encouraged to upgrade to this version as this release not
>    2. A few methods in the FastMath class are in fact slower that their
>    counterpart in either Math or StrictMath (cf. MATH-740 and MATH-901).
>  ">
> +      <action dev="luc" type="add" issue="MATH-1156" >
> +        Added all Java 8 StrictMath methods to FastMath, so FastMath remains compatible
> +        with newer Java versions.
> +      </action>
>        <action dev="tn" type="add" issue="MATH-1139" due-to="Alexey Volkov">
>          Added Gumbel, Laplace, Logistic and Nakagami distributions.
>        </action>
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
> ----------------------------------------------------------------------
> diff --git a/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java b/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
> index 617a2cc..b775440 100644
> --- a/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
> +++ b/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
> @@ -293,6 +293,7 @@ public enum LocalizedFormats implements Localizable {
>      OVERFLOW_IN_FRACTION("overflow in fraction {0}/{1}, cannot negate"),
>      OVERFLOW_IN_ADDITION("overflow in addition: {0} + {1}"),
>      OVERFLOW_IN_SUBTRACTION("overflow in subtraction: {0} - {1}"),
> +    OVERFLOW_IN_MULTIPLICATION("overflow in multiplication: {0} * {1}"),
>      PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD("cannot access {0} method in percentile implementation {1}"),
>      PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD("percentile implementation {0} does not support {1}"),
>      PERMUTATION_EXCEEDS_N("permutation size ({0}) exceeds permuation domain ({1})"), /* keep */
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/main/java/org/apache/commons/math3/util/FastMath.java
> ----------------------------------------------------------------------
> diff --git a/src/main/java/org/apache/commons/math3/util/FastMath.java b/src/main/java/org/apache/commons/math3/util/FastMath.java
> index d16406a..9ed4c04 100644
> --- a/src/main/java/org/apache/commons/math3/util/FastMath.java
> +++ b/src/main/java/org/apache/commons/math3/util/FastMath.java
> @@ -18,6 +18,9 @@ package org.apache.commons.math3.util;
>
>  import java.io.PrintStream;
>
> +import org.apache.commons.math3.exception.MathArithmeticException;
> +import org.apache.commons.math3.exception.util.LocalizedFormats;
> +
>  /**
>   * Faster, more accurate, portable alternative to {@link Math} and
>   * {@link StrictMath} for large scale computation.
> @@ -804,6 +807,24 @@ public class FastMath {
>          return nextAfter(a, Float.POSITIVE_INFINITY);
>      }
>
> +    /** Compute next number towards negative infinity.
> +     * @param a number to which neighbor should be computed
> +     * @return neighbor of a towards negative infinity
> +     * @since 3.4
> +     */
> +    public static double nextDown(final double a) {
> +        return nextAfter(a, Double.NEGATIVE_INFINITY);
> +    }
> +
> +    /** Compute next number towards negative infinity.
> +     * @param a number to which neighbor should be computed
> +     * @return neighbor of a towards negative infinity
> +     * @since 3.4
> +     */
> +    public static float nextDown(final float a) {
> +        return nextAfter(a, Float.NEGATIVE_INFINITY);
> +    }
> +
>      /** Returns a pseudo-random number between 0.0 and 1.0.
>       * <p><b>Note:</b> this implementation currently delegates to {@link Math#random}
>       * @return a random number between 0.0 and 1.0
> @@ -3634,6 +3655,319 @@ public class FastMath {
>          return StrictMath.IEEEremainder(dividend, divisor); // TODO provide our own implementation
>      }
>
> +    /** Convert a long to interger, detecting overflows
> +     * @param n number to convert to int
> +     * @return integer with same valie as n if no overflows occur
> +     * @exception MathArithmeticException if n cannot fit into an int
> +     * @since 3.4
> +     */
> +    public static int toIntExact(final long n) throws MathArithmeticException {
> +        if (n < Integer.MIN_VALUE || n > Integer.MAX_VALUE) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW);
> +        }
> +        return (int) n;
> +    }
> +
> +    /** Increment a number, detecting overflows.
> +     * @param n number to increment
> +     * @return n+1 if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static int incrementExact(final int n) throws MathArithmeticException {
> +
> +        if (n == Integer.MAX_VALUE) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, n, 1);
> +        }
> +
> +        return n + 1;
> +
> +    }
> +
> +    /** Increment a number, detecting overflows.
> +     * @param n number to increment
> +     * @return n+1 if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static long incrementExact(final long n) throws MathArithmeticException {
> +
> +        if (n == Long.MAX_VALUE) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, n, 1);
> +        }
> +
> +        return n + 1;
> +
> +    }
> +
> +    /** Decrement a number, detecting overflows.
> +     * @param n number to decrement
> +     * @return n-1 if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static int decrementExact(final int n) throws MathArithmeticException {
> +
> +        if (n == Integer.MIN_VALUE) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, n, 1);
> +        }
> +
> +        return n - 1;
> +
> +    }
> +
> +    /** Decrement a number, detecting overflows.
> +     * @param n number to decrement
> +     * @return n-1 if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static long decrementExact(final long n) throws MathArithmeticException {
> +
> +        if (n == Long.MIN_VALUE) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, n, 1);
> +        }
> +
> +        return n - 1;
> +
> +    }
> +
> +    /** Add two numbers, detecting overflows.
> +     * @param a first number to add
> +     * @param b second number to add
> +     * @return a+b if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static int addExact(final int a, final int b) throws MathArithmeticException {
> +
> +        // compute sum
> +        final int sum = a + b;
> +
> +        // check for overflow
> +        if ((a ^ b) >= 0 && (sum ^ b) < 0) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, a, b);
> +        }
> +
> +        return sum;
> +
> +    }
> +
> +    /** Add two numbers, detecting overflows.
> +     * @param a first number to add
> +     * @param b second number to add
> +     * @return a+b if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static long addExact(final long a, final long b) throws MathArithmeticException {
> +
> +        // compute sum
> +        final long sum = a + b;
> +
> +        // check for overflow
> +        if ((a ^ b) >= 0 && (sum ^ b) < 0) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, a, b);
> +        }
> +
> +        return sum;
> +
> +    }
> +
> +    /** Subtract two numbers, detecting overflows.
> +     * @param a first number
> +     * @param b second number to subtract from a
> +     * @return a-b if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static int subtractExact(final int a, final int b) {
> +
> +        // compute subtraction
> +        final int sub = a - b;
> +
> +        // check for overflow
> +        if ((a ^ b) < 0 && (sub ^ b) >= 0) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, a, b);
> +        }
> +
> +        return sub;
> +
> +    }
> +
> +    /** Subtract two numbers, detecting overflows.
> +     * @param a first number
> +     * @param b second number to subtract from a
> +     * @return a-b if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static long subtractExact(final long a, final long b) {
> +
> +        // compute subtraction
> +        final long sub = a - b;
> +
> +        // check for overflow
> +        if ((a ^ b) < 0 && (sub ^ b) >= 0) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, a, b);
> +        }
> +
> +        return sub;
> +
> +    }
> +
> +    /** Multiply two numbers, detecting overflows.
> +     * @param a first number to multiply
> +     * @param b second number to multiply
> +     * @return a*b if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static int multiplyExact(final int a, final int b) {
> +        if (((b  >  0)  && (a > Integer.MAX_VALUE / b || a < Integer.MIN_VALUE / b)) ||
> +            ((b  < -1)  && (a > Integer.MIN_VALUE / b || a < Integer.MAX_VALUE / b)) ||
> +            ((b == -1)  && (a == Integer.MIN_VALUE))) {
> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_MULTIPLICATION, a, b);
> +        }
> +        return a * b;
> +    }
> +
> +    /** Multiply two numbers, detecting overflows.
> +     * @param a first number to multiply
> +     * @param b second number to multiply
> +     * @return a*b if no overflows occur
> +     * @exception MathArithmeticException if an overflow occurs
> +     * @since 3.4
> +     */
> +    public static long multiplyExact(final long a, final long b) {
> +        if (((b  >  0l)  && (a > Long.MAX_VALUE / b || a < Long.MIN_VALUE / b)) ||
> +            ((b  < -1l)  && (a > Long.MIN_VALUE / b || a < Long.MAX_VALUE / b)) ||
> +            ((b == -1l)  && (a == Long.MIN_VALUE))) {
> +                throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_MULTIPLICATION, a, b);
> +            }
> +            return a * b;
> +    }
> +
> +    /** Finds q such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0.
> +     * <p>
> +     * This methods returns the same value as integer division when
> +     * a and b are same signs, but returns a different value when
> +     * they are opposite (i.e. q is negative).
> +     * </p>
> +     * @param a dividend
> +     * @param b divisor
> +     * @return q such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0
> +     * @exception MathArithmeticException if b == 0
> +     * @see #floorMod(int, int)
> +     * @since 3.4
> +     */
> +    public static int floorDiv(final int a, final int b) throws MathArithmeticException {
> +
> +        if (b == 0) {
> +            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
> +        }
> +
> +        final int m = a % b;
> +        if ((a ^ b) >= 0 || m == 0) {
> +            // a an b have same sign, or division is exact
> +            return a / b;
> +        } else {
> +            // a and b have opposite signs and division is not exact
> +            return (a / b) - 1;
> +        }
> +
> +    }
> +
> +    /** Finds q such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0.
> +     * <p>
> +     * This methods returns the same value as integer division when
> +     * a and b are same signs, but returns a different value when
> +     * they are opposite (i.e. q is negative).
> +     * </p>
> +     * @param a dividend
> +     * @param b divisor
> +     * @return q such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0
> +     * @exception MathArithmeticException if b == 0
> +     * @see #floorMod(long, long)
> +     * @since 3.4
> +     */
> +    public static long floorDiv(final long a, final long b) throws MathArithmeticException {
> +
> +        if (b == 0l) {
> +            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
> +        }
> +
> +        final long m = a % b;
> +        if ((a ^ b) >= 0l || m == 0l) {
> +            // a an b have same sign, or division is exact
> +            return a / b;
> +        } else {
> +            // a and b have opposite signs and division is not exact
> +            return (a / b) - 1l;
> +        }
> +
> +    }
> +
> +    /** Finds r such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0.
> +     * <p>
> +     * This methods returns the same value as integer modulo when
> +     * a and b are same signs, but returns a different value when
> +     * they are opposite (i.e. q is negative).
> +     * </p>
> +     * @param a dividend
> +     * @param b divisor
> +     * @return r such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0
> +     * @exception MathArithmeticException if b == 0
> +     * @see #floorDiv(int, int)
> +     * @since 3.4
> +     */
> +    public static int floorMod(final int a, final int b) throws MathArithmeticException {
> +
> +        if (b == 0) {
> +            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
> +        }
> +
> +        final int m = a % b;
> +        if ((a ^ b) >= 0 || m == 0) {
> +            // a an b have same sign, or division is exact
> +            return m;
> +        } else {
> +            // a and b have opposite signs and division is not exact
> +            return b + m;
> +        }
> +
> +    }
> +
> +    /** Finds r such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0.
> +     * <p>
> +     * This methods returns the same value as integer modulo when
> +     * a and b are same signs, but returns a different value when
> +     * they are opposite (i.e. q is negative).
> +     * </p>
> +     * @param a dividend
> +     * @param b divisor
> +     * @return r such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0
> +     * @exception MathArithmeticException if b == 0
> +     * @see #floorDiv(long, long)
> +     * @since 3.4
> +     */
> +    public static long floorMod(final long a, final long b) {
> +
> +        if (b == 0l) {
> +            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
> +        }
> +
> +        final long m = a % b;
> +        if ((a ^ b) >= 0l || m == 0l) {
> +            // a an b have same sign, or division is exact
> +            return m;
> +        } else {
> +            // a and b have opposite signs and division is not exact
> +            return b + m;
> +        }
> +
> +    }
> +
>      /**
>       * Returns the first argument with the sign of the second argument.
>       * A NaN {@code sign} argument is treated as positive.
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
> ----------------------------------------------------------------------
> diff --git a/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties b/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
> index 1a3c239..599dc7f 100644
> --- a/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
> +++ b/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
> @@ -265,6 +265,7 @@ OVERFLOW = d\u00e9passement de capacit\u00e9
>  OVERFLOW_IN_FRACTION = d\u00e9passement de capacit\u00e9 pour la fraction {0}/{1}, son signe ne peut \u00eatre chang\u00e9
>  OVERFLOW_IN_ADDITION = d\u00e9passement de capacit\u00e9 pour l''addition : {0} + {1}
>  OVERFLOW_IN_SUBTRACTION = d\u00e9passement de capacit\u00e9 pour la soustraction : {0} - {1}
> +OVERFLOW_IN_MULTIPLICATION = d\u00e9passement de capacit\u00e9 pour la multiplication : {0} * {1}
>  PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD = acc\u00e8s impossible \u00e0 la m\u00e9thode {0} dans la mise en \u0153uvre du pourcentage {1}
>  PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD = l''implantation de pourcentage {0} ne dispose pas de la m\u00e9thode {1}
>  PERMUTATION_EXCEEDS_N = la taille de la permutation ({0}) d\u00e9passe le domaine de la permutation ({1})
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
> ----------------------------------------------------------------------
> diff --git a/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java b/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
> index 24d5bbc..34344d4 100644
> --- a/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
> +++ b/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
> @@ -23,14 +23,13 @@ import java.util.Locale;
>  import java.util.ResourceBundle;
>
>  import org.junit.Assert;
> -
>  import org.junit.Test;
>
>  public class LocalizedFormatsTest {
>
>      @Test
>      public void testMessageNumber() {
> -        Assert.assertEquals(319, LocalizedFormats.values().length);
> +        Assert.assertEquals(320, LocalizedFormats.values().length);
>      }
>
>      @Test
>
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/test/java/org/apache/commons/math3/util/FastMathTest.java
> ----------------------------------------------------------------------
> diff --git a/src/test/java/org/apache/commons/math3/util/FastMathTest.java b/src/test/java/org/apache/commons/math3/util/FastMathTest.java
> index 8408b78..f860754 100644
> --- a/src/test/java/org/apache/commons/math3/util/FastMathTest.java
> +++ b/src/test/java/org/apache/commons/math3/util/FastMathTest.java
> @@ -19,13 +19,16 @@ package org.apache.commons.math3.util;
>  import java.lang.reflect.Method;
>  import java.lang.reflect.Modifier;
>  import java.lang.reflect.Type;
> +import java.math.BigInteger;
>
>  import org.apache.commons.math3.TestUtils;
>  import org.apache.commons.math3.dfp.Dfp;
>  import org.apache.commons.math3.dfp.DfpField;
>  import org.apache.commons.math3.dfp.DfpMath;
> +import org.apache.commons.math3.exception.MathArithmeticException;
>  import org.apache.commons.math3.random.MersenneTwister;
>  import org.apache.commons.math3.random.RandomGenerator;
> +import org.apache.commons.math3.random.Well1024a;
>  import org.junit.Assert;
>  import org.junit.Before;
>  import org.junit.Ignore;
> @@ -958,13 +961,13 @@ public class FastMathTest {
>      @Test
>      public void testNextAfter() {
>          // 0x402fffffffffffff 0x404123456789abcd -> 4030000000000000
> -        Assert.assertEquals(16.0, FastMath.nextAfter(15.999999999999998, 34.27555555555555), 0.0);
> +        Assert.assertEquals(16.0, FastMath.nextUp(15.999999999999998), 0.0);
>
>          // 0xc02fffffffffffff 0x404123456789abcd -> c02ffffffffffffe
>          Assert.assertEquals(-15.999999999999996, FastMath.nextAfter(-15.999999999999998, 34.27555555555555), 0.0);
>
>          // 0x402fffffffffffff 0x400123456789abcd -> 402ffffffffffffe
> -        Assert.assertEquals(15.999999999999996, FastMath.nextAfter(15.999999999999998, 2.142222222222222), 0.0);
> +        Assert.assertEquals(15.999999999999996, FastMath.nextDown(15.999999999999998), 0.0);
>
>          // 0xc02fffffffffffff 0x400123456789abcd -> c02ffffffffffffe
>          Assert.assertEquals(-15.999999999999996, FastMath.nextAfter(-15.999999999999998, 2.142222222222222), 0.0);
> @@ -1037,8 +1040,8 @@ public class FastMathTest {
>          Assert.assertEquals(-Float.MAX_VALUE,FastMath.nextAfter(Float.NEGATIVE_INFINITY, 0F), 0F);
>          Assert.assertEquals(Float.MAX_VALUE,FastMath.nextAfter(Float.POSITIVE_INFINITY, 0F), 0F);
>          Assert.assertEquals(Float.NaN,FastMath.nextAfter(Float.NaN, 0F), 0F);
> -        Assert.assertEquals(Float.POSITIVE_INFINITY,FastMath.nextAfter(Float.MAX_VALUE, Float.POSITIVE_INFINITY), 0F);
> -        Assert.assertEquals(Float.NEGATIVE_INFINITY,FastMath.nextAfter(-Float.MAX_VALUE, Float.NEGATIVE_INFINITY), 0F);
> +        Assert.assertEquals(Float.POSITIVE_INFINITY,FastMath.nextUp(Float.MAX_VALUE), 0F);
> +        Assert.assertEquals(Float.NEGATIVE_INFINITY,FastMath.nextDown(-Float.MAX_VALUE), 0F);
>          Assert.assertEquals(Float.MIN_VALUE, FastMath.nextAfter(0F, 1F), 0F);
>          Assert.assertEquals(-Float.MIN_VALUE, FastMath.nextAfter(0F, -1F), 0F);
>          Assert.assertEquals(0F, FastMath.nextAfter(Float.MIN_VALUE, -1F), 0F);
> @@ -1182,4 +1185,422 @@ public class FastMathTest {
>          }
>      }
>
> +    @Test
> +    public void testIncrementExactInt() {
> +        int[] specialValues = new int[] {
> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
> +        };
> +        for (int a : specialValues) {
> +            BigInteger bdA   = BigInteger.valueOf(a);
> +            BigInteger bdSum = bdA.add(BigInteger.ONE);
> +            if (bdSum.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
> +                bdSum.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
> +                try {
> +                    FastMath.incrementExact(a);
> +                    Assert.fail("an exception should have been thrown");
> +                } catch (MathArithmeticException mae) {
> +                    // expected
> +                }
> +            } else {
> +                Assert.assertEquals(bdSum, BigInteger.valueOf(FastMath.incrementExact(a)));
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testDecrementExactInt() {
> +        int[] specialValues = new int[] {
> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
> +        };
> +        for (int a : specialValues) {
> +            BigInteger bdA   = BigInteger.valueOf(a);
> +            BigInteger bdSub = bdA.subtract(BigInteger.ONE);
> +            if (bdSub.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
> +                bdSub.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
> +                try {
> +                    FastMath.decrementExact(a);
> +                    Assert.fail("an exception should have been thrown");
> +                } catch (MathArithmeticException mae) {
> +                    // expected
> +                }
> +            } else {
> +                Assert.assertEquals(bdSub, BigInteger.valueOf(FastMath.decrementExact(a)));
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testAddExactInt() {
> +        int[] specialValues = new int[] {
> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
> +        };
> +        for (int a : specialValues) {
> +            for (int b : specialValues) {
> +                BigInteger bdA   = BigInteger.valueOf(a);
> +                BigInteger bdB   = BigInteger.valueOf(b);
> +                BigInteger bdSum = bdA.add(bdB);
> +                if (bdSum.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
> +                        bdSum.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
> +                    try {
> +                        FastMath.addExact(a, b);
> +                        Assert.fail("an exception should have been thrown");
> +                    } catch (MathArithmeticException mae) {
> +                        // expected
> +                    }
> +                } else {
> +                    Assert.assertEquals(bdSum, BigInteger.valueOf(FastMath.addExact(a, b)));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testAddExactLong() {
> +        long[] specialValues = new long[] {
> +            Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MIN_VALUE + 2,
> +            Long.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE - 2,
> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
> +            -1 - (Long.MIN_VALUE / 2), 0 - (Long.MIN_VALUE / 2), 1 - (Long.MIN_VALUE / 2),
> +            -1 + (Long.MAX_VALUE / 2), 0 + (Long.MAX_VALUE / 2), 1 + (Long.MAX_VALUE / 2),
> +        };
> +        for (long a : specialValues) {
> +            for (long b : specialValues) {
> +                BigInteger bdA   = BigInteger.valueOf(a);
> +                BigInteger bdB   = BigInteger.valueOf(b);
> +                BigInteger bdSum = bdA.add(bdB);
> +                if (bdSum.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0 ||
> +                        bdSum.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
> +                    try {
> +                        FastMath.addExact(a, b);
> +                        Assert.fail("an exception should have been thrown");
> +                    } catch (MathArithmeticException mae) {
> +                        // expected
> +                    }
> +                } else {
> +                    Assert.assertEquals(bdSum, BigInteger.valueOf(FastMath.addExact(a, b)));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testSubtractExactInt() {
> +        int[] specialValues = new int[] {
> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
> +        };
> +        for (int a : specialValues) {
> +            for (int b : specialValues) {
> +                BigInteger bdA   = BigInteger.valueOf(a);
> +                BigInteger bdB   = BigInteger.valueOf(b);
> +                BigInteger bdSub = bdA.subtract(bdB);
> +                if (bdSub.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
> +                        bdSub.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
> +                    try {
> +                        FastMath.subtractExact(a, b);
> +                        Assert.fail("an exception should have been thrown");
> +                    } catch (MathArithmeticException mae) {
> +                        // expected
> +                    }
> +                } else {
> +                    Assert.assertEquals(bdSub, BigInteger.valueOf(FastMath.subtractExact(a, b)));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testSubtractExactLong() {
> +        long[] specialValues = new long[] {
> +            Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MIN_VALUE + 2,
> +            Long.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE - 2,
> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
> +            -1 - (Long.MIN_VALUE / 2), 0 - (Long.MIN_VALUE / 2), 1 - (Long.MIN_VALUE / 2),
> +            -1 + (Long.MAX_VALUE / 2), 0 + (Long.MAX_VALUE / 2), 1 + (Long.MAX_VALUE / 2),
> +        };
> +        for (long a : specialValues) {
> +            for (long b : specialValues) {
> +                BigInteger bdA   = BigInteger.valueOf(a);
> +                BigInteger bdB   = BigInteger.valueOf(b);
> +                BigInteger bdSub = bdA.subtract(bdB);
> +                if (bdSub.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0 ||
> +                        bdSub.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
> +                    try {
> +                        FastMath.subtractExact(a, b);
> +                        Assert.fail("an exception should have been thrown");
> +                    } catch (MathArithmeticException mae) {
> +                        // expected
> +                    }
> +                } else {
> +                    Assert.assertEquals(bdSub, BigInteger.valueOf(FastMath.subtractExact(a, b)));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testMultiplyExactInt() {
> +        int[] specialValues = new int[] {
> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
> +        };
> +        for (int a : specialValues) {
> +            for (int b : specialValues) {
> +                BigInteger bdA   = BigInteger.valueOf(a);
> +                BigInteger bdB   = BigInteger.valueOf(b);
> +                BigInteger bdMul = bdA.multiply(bdB);
> +                if (bdMul.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
> +                        bdMul.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
> +                    try {
> +                        FastMath.multiplyExact(a, b);
> +                        Assert.fail("an exception should have been thrown " + a + b);
> +                    } catch (MathArithmeticException mae) {
> +                        // expected
> +                    }
> +                } else {
> +                    Assert.assertEquals(bdMul, BigInteger.valueOf(FastMath.multiplyExact(a, b)));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testMultiplyExactLong() {
> +        long[] specialValues = new long[] {
> +            Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MIN_VALUE + 2,
> +            Long.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE - 2,
> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
> +            -1 - (Long.MIN_VALUE / 2), 0 - (Long.MIN_VALUE / 2), 1 - (Long.MIN_VALUE / 2),
> +            -1 + (Long.MAX_VALUE / 2), 0 + (Long.MAX_VALUE / 2), 1 + (Long.MAX_VALUE / 2),
> +        };
> +        for (long a : specialValues) {
> +            for (long b : specialValues) {
> +                BigInteger bdA   = BigInteger.valueOf(a);
> +                BigInteger bdB   = BigInteger.valueOf(b);
> +                BigInteger bdMul = bdA.multiply(bdB);
> +                if (bdMul.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0 ||
> +                        bdMul.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
> +                    try {
> +                        FastMath.multiplyExact(a, b);
> +                        Assert.fail("an exception should have been thrown " + a + b);
> +                    } catch (MathArithmeticException mae) {
> +                        // expected
> +                    }
> +                } else {
> +                    Assert.assertEquals(bdMul, BigInteger.valueOf(FastMath.multiplyExact(a, b)));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test(expected=MathArithmeticException.class)
> +    public void testToIntExactTooLow() {
> +        FastMath.toIntExact(-1l + Integer.MIN_VALUE);
> +    }
> +
> +    @Test(expected=MathArithmeticException.class)
> +    public void testToIntExactTooHigh() {
> +        FastMath.toIntExact(+1l + Integer.MAX_VALUE);
> +    }
> +
> +    @Test
> +    public void testToIntExact() {
> +        for (int n = -1000; n < 1000; ++n) {
> +            Assert.assertEquals(n, FastMath.toIntExact(0l + n));
> +        }
> +        Assert.assertEquals(Integer.MIN_VALUE, FastMath.toIntExact(0l + Integer.MIN_VALUE));
> +        Assert.assertEquals(Integer.MAX_VALUE, FastMath.toIntExact(0l + Integer.MAX_VALUE));
> +    }
> +
> +    @Test
> +    public void testFloorDivInt() {
> +        Assert.assertEquals(+1, FastMath.floorDiv(+4, +3));
> +        Assert.assertEquals(-2, FastMath.floorDiv(-4, +3));
> +        Assert.assertEquals(-2, FastMath.floorDiv(+4, -3));
> +        Assert.assertEquals(+1, FastMath.floorDiv(-4, -3));
> +        try {
> +            FastMath.floorDiv(1, 0);
> +            Assert.fail("an exception should have been thrown");
> +        } catch (MathArithmeticException mae) {
> +            // expected
> +        }
> +        for (int a = -100; a <= 100; ++a) {
> +            for (int b = -100; b <= 100; ++b) {
> +                if (b != 0) {
> +                    Assert.assertEquals(poorManFloorDiv(a, b), FastMath.floorDiv(a, b));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testFloorModInt() {
> +        Assert.assertEquals(+1, FastMath.floorMod(+4, +3));
> +        Assert.assertEquals(+2, FastMath.floorMod(-4, +3));
> +        Assert.assertEquals(-2, FastMath.floorMod(+4, -3));
> +        Assert.assertEquals(-1, FastMath.floorMod(-4, -3));
> +        try {
> +            FastMath.floorMod(1, 0);
> +            Assert.fail("an exception should have been thrown");
> +        } catch (MathArithmeticException mae) {
> +            // expected
> +        }
> +        for (int a = -100; a <= 100; ++a) {
> +            for (int b = -100; b <= 100; ++b) {
> +                if (b != 0) {
> +                    Assert.assertEquals(poorManFloorMod(a, b), FastMath.floorMod(a, b));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testFloorDivModInt() {
> +        RandomGenerator generator = new Well1024a(0x7ccab45edeaab90al);
> +        for (int i = 0; i < 10000; ++i) {
> +            int a = generator.nextInt();
> +            int b = generator.nextInt();
> +            if (b == 0) {
> +                try {
> +                    FastMath.floorDiv(a, b);
> +                    Assert.fail("an exception should have been thrown");
> +                } catch (MathArithmeticException mae) {
> +                    // expected
> +                }
> +            } else {
> +                int d = FastMath.floorDiv(a, b);
> +                int m = FastMath.floorMod(a, b);
> +                Assert.assertEquals(FastMath.toIntExact(poorManFloorDiv(a, b)), d);
> +                Assert.assertEquals(FastMath.toIntExact(poorManFloorMod(a, b)), m);
> +                Assert.assertEquals(a, d * b + m);
> +                if (b < 0) {
> +                    Assert.assertTrue(m <= 0);
> +                    Assert.assertTrue(-m < -b);
> +                } else {
> +                    Assert.assertTrue(m >= 0);
> +                    Assert.assertTrue(m < b);
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testFloorDivLong() {
> +        Assert.assertEquals(+1l, FastMath.floorDiv(+4l, +3l));
> +        Assert.assertEquals(-2l, FastMath.floorDiv(-4l, +3l));
> +        Assert.assertEquals(-2l, FastMath.floorDiv(+4l, -3l));
> +        Assert.assertEquals(+1l, FastMath.floorDiv(-4l, -3l));
> +        try {
> +            FastMath.floorDiv(1l, 0l);
> +            Assert.fail("an exception should have been thrown");
> +        } catch (MathArithmeticException mae) {
> +            // expected
> +        }
> +        for (long a = -100l; a <= 100l; ++a) {
> +            for (long b = -100l; b <= 100l; ++b) {
> +                if (b != 0) {
> +                    Assert.assertEquals(poorManFloorDiv(a, b), FastMath.floorDiv(a, b));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testFloorModLong() {
> +        Assert.assertEquals(+1l, FastMath.floorMod(+4l, +3l));
> +        Assert.assertEquals(+2l, FastMath.floorMod(-4l, +3l));
> +        Assert.assertEquals(-2l, FastMath.floorMod(+4l, -3l));
> +        Assert.assertEquals(-1l, FastMath.floorMod(-4l, -3l));
> +        try {
> +            FastMath.floorMod(1l, 0l);
> +            Assert.fail("an exception should have been thrown");
> +        } catch (MathArithmeticException mae) {
> +            // expected
> +        }
> +        for (long a = -100l; a <= 100l; ++a) {
> +            for (long b = -100l; b <= 100l; ++b) {
> +                if (b != 0) {
> +                    Assert.assertEquals(poorManFloorMod(a, b), FastMath.floorMod(a, b));
> +                }
> +            }
> +        }
> +    }
> +
> +    @Test
> +    public void testFloorDivModLong() {
> +        RandomGenerator generator = new Well1024a(0xb87b9bc14c96ccd5l);
> +        for (int i = 0; i < 10000; ++i) {
> +            long a = generator.nextLong();
> +            long b = generator.nextLong();
> +            if (b == 0) {
> +                try {
> +                    FastMath.floorDiv(a, b);
> +                    Assert.fail("an exception should have been thrown");
> +                } catch (MathArithmeticException mae) {
> +                    // expected
> +                }
> +            } else {
> +                long d = FastMath.floorDiv(a, b);
> +                long m = FastMath.floorMod(a, b);
> +                Assert.assertEquals(poorManFloorDiv(a, b), d);
> +                Assert.assertEquals(poorManFloorMod(a, b), m);
> +                Assert.assertEquals(a, d * b + m);
> +                if (b < 0) {
> +                    Assert.assertTrue(m <= 0);
> +                    Assert.assertTrue(-m < -b);
> +                } else {
> +                    Assert.assertTrue(m >= 0);
> +                    Assert.assertTrue(m < b);
> +                }
> +            }
> +        }
> +    }
> +
> +    private long poorManFloorDiv(long a, long b) {
> +
> +        // find q0, r0 such that a = q0 b + r0
> +        BigInteger q0 = BigInteger.valueOf(a / b);
> +        BigInteger r0 = BigInteger.valueOf(a % b);
> +        BigInteger fd = BigInteger.valueOf(Integer.MIN_VALUE);
> +        BigInteger bigB = BigInteger.valueOf(b);
> +
> +        for (int k = -2; k < 2; ++k) {
> +            // find another pair q, r such that a = q b + r
> +            BigInteger bigK = BigInteger.valueOf(k);
> +            BigInteger q = q0.subtract(bigK);
> +            BigInteger r = r0.add(bigK.multiply(bigB));
> +            if (r.abs().compareTo(bigB.abs()) < 0 &&
> +                (r.longValue() == 0l || ((r.longValue() ^ b) & 0x8000000000000000l) == 0)) {
> +                if (fd.compareTo(q) < 0) {
> +                    fd = q;
> +                }
> +            }
> +        }
> +
> +        return fd.longValue();
> +
> +    }
> +
> +    private long poorManFloorMod(long a, long b) {
> +        return a - b * poorManFloorDiv(a, b);
> +    }
> +
>  }
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: git commit: Added all Java 8 StrictMath methods to FastMath.

Posted by Luc Maisonobe <lu...@spaceroots.org>.
Hi Sebb,

Le 07/10/2014 23:40, sebb a écrit :
> On 7 October 2014 12:55,  <lu...@apache.org> wrote:
>> Repository: commons-math
>> Updated Branches:
>>   refs/heads/master cee04d164 -> a67f0a33e
>>
>>
>> Added all Java 8 StrictMath methods to FastMath.
>>
>> This change allows FastMath to remain compatible with newer Java
>> versions, despite it stiil requires only Java 5 to compile and run.
>>
>> JIRA: MATH-1156
>>
>>
>> Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
>> Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/a67f0a33
>> Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/a67f0a33
>> Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/a67f0a33
>>
>> Branch: refs/heads/master
>> Commit: a67f0a33e68abf1c985db28b19ce70f427fd48bd
>> Parents: cee04d1
>> Author: Luc Maisonobe <lu...@apache.org>
>> Authored: Tue Oct 7 13:54:55 2014 +0200
>> Committer: Luc Maisonobe <lu...@apache.org>
>> Committed: Tue Oct 7 13:54:55 2014 +0200
>>
>> ----------------------------------------------------------------------
>>  pom.xml                                         |   6 +-
>>  src/changes/changes.xml                         |   4 +
>>  .../math3/exception/util/LocalizedFormats.java  |   1 +
>>  .../org/apache/commons/math3/util/FastMath.java | 334 +++++++++++++++
>>  .../util/LocalizedFormats_fr.properties         |   1 +
>>  .../exception/util/LocalizedFormatsTest.java    |   3 +-
>>  .../apache/commons/math3/util/FastMathTest.java | 429 ++++++++++++++++++-
>>  7 files changed, 769 insertions(+), 9 deletions(-)
>> ----------------------------------------------------------------------
>>
>>
>> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/pom.xml
>> ----------------------------------------------------------------------
>> diff --git a/pom.xml b/pom.xml
>> index 3ca4958..3a62e60 100644
>> --- a/pom.xml
>> +++ b/pom.xml
>> @@ -38,9 +38,9 @@
>>    </issueManagement>
>>
>>    <scm>
>> -    <connection>scm:svn:http://svn.apache.org/repos/asf/commons/proper/math/trunk</connection>
>> -    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/commons/proper/math/trunk</developerConnection>
>> -    <url>http://svn.apache.org/viewvc/commons/proper/math/trunk</url>
>> +    <connection>scm:git:http://git-wip-us.apache.org/repos/asf/commons-math.git</connection>
>> +    <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/commons-math.git</developerConnection>
>> +    <url>https://git-wip-us.apache.org/repos/asf?p=commons-math.git</url>
>>    </scm>
> 
> The pom.xml change appears to belong to a different commit; it does
> not seem to relate to the log message.

Nice catch, thanks.

It seems to be an error. This change was intended to be in a commit of
its own, and I obviously forgot to do it. It seems I make more and more
errors like this as I'm getting older (I turned 50 a few days ago ;-)

I sincerely try to be more careful, sorry

best regards,
Luc

> 
>>    <distributionManagement>
>>
>> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/changes/changes.xml
>> ----------------------------------------------------------------------
>> diff --git a/src/changes/changes.xml b/src/changes/changes.xml
>> index 0c6520b..7ea96c9 100644
>> --- a/src/changes/changes.xml
>> +++ b/src/changes/changes.xml
>> @@ -73,6 +73,10 @@ Users are encouraged to upgrade to this version as this release not
>>    2. A few methods in the FastMath class are in fact slower that their
>>    counterpart in either Math or StrictMath (cf. MATH-740 and MATH-901).
>>  ">
>> +      <action dev="luc" type="add" issue="MATH-1156" >
>> +        Added all Java 8 StrictMath methods to FastMath, so FastMath remains compatible
>> +        with newer Java versions.
>> +      </action>
>>        <action dev="tn" type="add" issue="MATH-1139" due-to="Alexey Volkov">
>>          Added Gumbel, Laplace, Logistic and Nakagami distributions.
>>        </action>
>>
>> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
>> ----------------------------------------------------------------------
>> diff --git a/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java b/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
>> index 617a2cc..b775440 100644
>> --- a/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
>> +++ b/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
>> @@ -293,6 +293,7 @@ public enum LocalizedFormats implements Localizable {
>>      OVERFLOW_IN_FRACTION("overflow in fraction {0}/{1}, cannot negate"),
>>      OVERFLOW_IN_ADDITION("overflow in addition: {0} + {1}"),
>>      OVERFLOW_IN_SUBTRACTION("overflow in subtraction: {0} - {1}"),
>> +    OVERFLOW_IN_MULTIPLICATION("overflow in multiplication: {0} * {1}"),
>>      PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD("cannot access {0} method in percentile implementation {1}"),
>>      PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD("percentile implementation {0} does not support {1}"),
>>      PERMUTATION_EXCEEDS_N("permutation size ({0}) exceeds permuation domain ({1})"), /* keep */
>>
>> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/main/java/org/apache/commons/math3/util/FastMath.java
>> ----------------------------------------------------------------------
>> diff --git a/src/main/java/org/apache/commons/math3/util/FastMath.java b/src/main/java/org/apache/commons/math3/util/FastMath.java
>> index d16406a..9ed4c04 100644
>> --- a/src/main/java/org/apache/commons/math3/util/FastMath.java
>> +++ b/src/main/java/org/apache/commons/math3/util/FastMath.java
>> @@ -18,6 +18,9 @@ package org.apache.commons.math3.util;
>>
>>  import java.io.PrintStream;
>>
>> +import org.apache.commons.math3.exception.MathArithmeticException;
>> +import org.apache.commons.math3.exception.util.LocalizedFormats;
>> +
>>  /**
>>   * Faster, more accurate, portable alternative to {@link Math} and
>>   * {@link StrictMath} for large scale computation.
>> @@ -804,6 +807,24 @@ public class FastMath {
>>          return nextAfter(a, Float.POSITIVE_INFINITY);
>>      }
>>
>> +    /** Compute next number towards negative infinity.
>> +     * @param a number to which neighbor should be computed
>> +     * @return neighbor of a towards negative infinity
>> +     * @since 3.4
>> +     */
>> +    public static double nextDown(final double a) {
>> +        return nextAfter(a, Double.NEGATIVE_INFINITY);
>> +    }
>> +
>> +    /** Compute next number towards negative infinity.
>> +     * @param a number to which neighbor should be computed
>> +     * @return neighbor of a towards negative infinity
>> +     * @since 3.4
>> +     */
>> +    public static float nextDown(final float a) {
>> +        return nextAfter(a, Float.NEGATIVE_INFINITY);
>> +    }
>> +
>>      /** Returns a pseudo-random number between 0.0 and 1.0.
>>       * <p><b>Note:</b> this implementation currently delegates to {@link Math#random}
>>       * @return a random number between 0.0 and 1.0
>> @@ -3634,6 +3655,319 @@ public class FastMath {
>>          return StrictMath.IEEEremainder(dividend, divisor); // TODO provide our own implementation
>>      }
>>
>> +    /** Convert a long to interger, detecting overflows
>> +     * @param n number to convert to int
>> +     * @return integer with same valie as n if no overflows occur
>> +     * @exception MathArithmeticException if n cannot fit into an int
>> +     * @since 3.4
>> +     */
>> +    public static int toIntExact(final long n) throws MathArithmeticException {
>> +        if (n < Integer.MIN_VALUE || n > Integer.MAX_VALUE) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW);
>> +        }
>> +        return (int) n;
>> +    }
>> +
>> +    /** Increment a number, detecting overflows.
>> +     * @param n number to increment
>> +     * @return n+1 if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static int incrementExact(final int n) throws MathArithmeticException {
>> +
>> +        if (n == Integer.MAX_VALUE) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, n, 1);
>> +        }
>> +
>> +        return n + 1;
>> +
>> +    }
>> +
>> +    /** Increment a number, detecting overflows.
>> +     * @param n number to increment
>> +     * @return n+1 if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static long incrementExact(final long n) throws MathArithmeticException {
>> +
>> +        if (n == Long.MAX_VALUE) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, n, 1);
>> +        }
>> +
>> +        return n + 1;
>> +
>> +    }
>> +
>> +    /** Decrement a number, detecting overflows.
>> +     * @param n number to decrement
>> +     * @return n-1 if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static int decrementExact(final int n) throws MathArithmeticException {
>> +
>> +        if (n == Integer.MIN_VALUE) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, n, 1);
>> +        }
>> +
>> +        return n - 1;
>> +
>> +    }
>> +
>> +    /** Decrement a number, detecting overflows.
>> +     * @param n number to decrement
>> +     * @return n-1 if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static long decrementExact(final long n) throws MathArithmeticException {
>> +
>> +        if (n == Long.MIN_VALUE) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, n, 1);
>> +        }
>> +
>> +        return n - 1;
>> +
>> +    }
>> +
>> +    /** Add two numbers, detecting overflows.
>> +     * @param a first number to add
>> +     * @param b second number to add
>> +     * @return a+b if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static int addExact(final int a, final int b) throws MathArithmeticException {
>> +
>> +        // compute sum
>> +        final int sum = a + b;
>> +
>> +        // check for overflow
>> +        if ((a ^ b) >= 0 && (sum ^ b) < 0) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, a, b);
>> +        }
>> +
>> +        return sum;
>> +
>> +    }
>> +
>> +    /** Add two numbers, detecting overflows.
>> +     * @param a first number to add
>> +     * @param b second number to add
>> +     * @return a+b if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static long addExact(final long a, final long b) throws MathArithmeticException {
>> +
>> +        // compute sum
>> +        final long sum = a + b;
>> +
>> +        // check for overflow
>> +        if ((a ^ b) >= 0 && (sum ^ b) < 0) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, a, b);
>> +        }
>> +
>> +        return sum;
>> +
>> +    }
>> +
>> +    /** Subtract two numbers, detecting overflows.
>> +     * @param a first number
>> +     * @param b second number to subtract from a
>> +     * @return a-b if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static int subtractExact(final int a, final int b) {
>> +
>> +        // compute subtraction
>> +        final int sub = a - b;
>> +
>> +        // check for overflow
>> +        if ((a ^ b) < 0 && (sub ^ b) >= 0) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, a, b);
>> +        }
>> +
>> +        return sub;
>> +
>> +    }
>> +
>> +    /** Subtract two numbers, detecting overflows.
>> +     * @param a first number
>> +     * @param b second number to subtract from a
>> +     * @return a-b if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static long subtractExact(final long a, final long b) {
>> +
>> +        // compute subtraction
>> +        final long sub = a - b;
>> +
>> +        // check for overflow
>> +        if ((a ^ b) < 0 && (sub ^ b) >= 0) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, a, b);
>> +        }
>> +
>> +        return sub;
>> +
>> +    }
>> +
>> +    /** Multiply two numbers, detecting overflows.
>> +     * @param a first number to multiply
>> +     * @param b second number to multiply
>> +     * @return a*b if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static int multiplyExact(final int a, final int b) {
>> +        if (((b  >  0)  && (a > Integer.MAX_VALUE / b || a < Integer.MIN_VALUE / b)) ||
>> +            ((b  < -1)  && (a > Integer.MIN_VALUE / b || a < Integer.MAX_VALUE / b)) ||
>> +            ((b == -1)  && (a == Integer.MIN_VALUE))) {
>> +            throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_MULTIPLICATION, a, b);
>> +        }
>> +        return a * b;
>> +    }
>> +
>> +    /** Multiply two numbers, detecting overflows.
>> +     * @param a first number to multiply
>> +     * @param b second number to multiply
>> +     * @return a*b if no overflows occur
>> +     * @exception MathArithmeticException if an overflow occurs
>> +     * @since 3.4
>> +     */
>> +    public static long multiplyExact(final long a, final long b) {
>> +        if (((b  >  0l)  && (a > Long.MAX_VALUE / b || a < Long.MIN_VALUE / b)) ||
>> +            ((b  < -1l)  && (a > Long.MIN_VALUE / b || a < Long.MAX_VALUE / b)) ||
>> +            ((b == -1l)  && (a == Long.MIN_VALUE))) {
>> +                throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_MULTIPLICATION, a, b);
>> +            }
>> +            return a * b;
>> +    }
>> +
>> +    /** Finds q such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0.
>> +     * <p>
>> +     * This methods returns the same value as integer division when
>> +     * a and b are same signs, but returns a different value when
>> +     * they are opposite (i.e. q is negative).
>> +     * </p>
>> +     * @param a dividend
>> +     * @param b divisor
>> +     * @return q such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0
>> +     * @exception MathArithmeticException if b == 0
>> +     * @see #floorMod(int, int)
>> +     * @since 3.4
>> +     */
>> +    public static int floorDiv(final int a, final int b) throws MathArithmeticException {
>> +
>> +        if (b == 0) {
>> +            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
>> +        }
>> +
>> +        final int m = a % b;
>> +        if ((a ^ b) >= 0 || m == 0) {
>> +            // a an b have same sign, or division is exact
>> +            return a / b;
>> +        } else {
>> +            // a and b have opposite signs and division is not exact
>> +            return (a / b) - 1;
>> +        }
>> +
>> +    }
>> +
>> +    /** Finds q such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0.
>> +     * <p>
>> +     * This methods returns the same value as integer division when
>> +     * a and b are same signs, but returns a different value when
>> +     * they are opposite (i.e. q is negative).
>> +     * </p>
>> +     * @param a dividend
>> +     * @param b divisor
>> +     * @return q such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0
>> +     * @exception MathArithmeticException if b == 0
>> +     * @see #floorMod(long, long)
>> +     * @since 3.4
>> +     */
>> +    public static long floorDiv(final long a, final long b) throws MathArithmeticException {
>> +
>> +        if (b == 0l) {
>> +            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
>> +        }
>> +
>> +        final long m = a % b;
>> +        if ((a ^ b) >= 0l || m == 0l) {
>> +            // a an b have same sign, or division is exact
>> +            return a / b;
>> +        } else {
>> +            // a and b have opposite signs and division is not exact
>> +            return (a / b) - 1l;
>> +        }
>> +
>> +    }
>> +
>> +    /** Finds r such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0.
>> +     * <p>
>> +     * This methods returns the same value as integer modulo when
>> +     * a and b are same signs, but returns a different value when
>> +     * they are opposite (i.e. q is negative).
>> +     * </p>
>> +     * @param a dividend
>> +     * @param b divisor
>> +     * @return r such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0
>> +     * @exception MathArithmeticException if b == 0
>> +     * @see #floorDiv(int, int)
>> +     * @since 3.4
>> +     */
>> +    public static int floorMod(final int a, final int b) throws MathArithmeticException {
>> +
>> +        if (b == 0) {
>> +            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
>> +        }
>> +
>> +        final int m = a % b;
>> +        if ((a ^ b) >= 0 || m == 0) {
>> +            // a an b have same sign, or division is exact
>> +            return m;
>> +        } else {
>> +            // a and b have opposite signs and division is not exact
>> +            return b + m;
>> +        }
>> +
>> +    }
>> +
>> +    /** Finds r such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0.
>> +     * <p>
>> +     * This methods returns the same value as integer modulo when
>> +     * a and b are same signs, but returns a different value when
>> +     * they are opposite (i.e. q is negative).
>> +     * </p>
>> +     * @param a dividend
>> +     * @param b divisor
>> +     * @return r such that a = q b + r with 0 <= r < b if b > 0 and b < r <= 0 if b > 0
>> +     * @exception MathArithmeticException if b == 0
>> +     * @see #floorDiv(long, long)
>> +     * @since 3.4
>> +     */
>> +    public static long floorMod(final long a, final long b) {
>> +
>> +        if (b == 0l) {
>> +            throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
>> +        }
>> +
>> +        final long m = a % b;
>> +        if ((a ^ b) >= 0l || m == 0l) {
>> +            // a an b have same sign, or division is exact
>> +            return m;
>> +        } else {
>> +            // a and b have opposite signs and division is not exact
>> +            return b + m;
>> +        }
>> +
>> +    }
>> +
>>      /**
>>       * Returns the first argument with the sign of the second argument.
>>       * A NaN {@code sign} argument is treated as positive.
>>
>> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
>> ----------------------------------------------------------------------
>> diff --git a/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties b/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
>> index 1a3c239..599dc7f 100644
>> --- a/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
>> +++ b/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
>> @@ -265,6 +265,7 @@ OVERFLOW = d\u00e9passement de capacit\u00e9
>>  OVERFLOW_IN_FRACTION = d\u00e9passement de capacit\u00e9 pour la fraction {0}/{1}, son signe ne peut \u00eatre chang\u00e9
>>  OVERFLOW_IN_ADDITION = d\u00e9passement de capacit\u00e9 pour l''addition : {0} + {1}
>>  OVERFLOW_IN_SUBTRACTION = d\u00e9passement de capacit\u00e9 pour la soustraction : {0} - {1}
>> +OVERFLOW_IN_MULTIPLICATION = d\u00e9passement de capacit\u00e9 pour la multiplication : {0} * {1}
>>  PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD = acc\u00e8s impossible \u00e0 la m\u00e9thode {0} dans la mise en \u0153uvre du pourcentage {1}
>>  PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD = l''implantation de pourcentage {0} ne dispose pas de la m\u00e9thode {1}
>>  PERMUTATION_EXCEEDS_N = la taille de la permutation ({0}) d\u00e9passe le domaine de la permutation ({1})
>>
>> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
>> ----------------------------------------------------------------------
>> diff --git a/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java b/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
>> index 24d5bbc..34344d4 100644
>> --- a/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
>> +++ b/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
>> @@ -23,14 +23,13 @@ import java.util.Locale;
>>  import java.util.ResourceBundle;
>>
>>  import org.junit.Assert;
>> -
>>  import org.junit.Test;
>>
>>  public class LocalizedFormatsTest {
>>
>>      @Test
>>      public void testMessageNumber() {
>> -        Assert.assertEquals(319, LocalizedFormats.values().length);
>> +        Assert.assertEquals(320, LocalizedFormats.values().length);
>>      }
>>
>>      @Test
>>
>> http://git-wip-us.apache.org/repos/asf/commons-math/blob/a67f0a33/src/test/java/org/apache/commons/math3/util/FastMathTest.java
>> ----------------------------------------------------------------------
>> diff --git a/src/test/java/org/apache/commons/math3/util/FastMathTest.java b/src/test/java/org/apache/commons/math3/util/FastMathTest.java
>> index 8408b78..f860754 100644
>> --- a/src/test/java/org/apache/commons/math3/util/FastMathTest.java
>> +++ b/src/test/java/org/apache/commons/math3/util/FastMathTest.java
>> @@ -19,13 +19,16 @@ package org.apache.commons.math3.util;
>>  import java.lang.reflect.Method;
>>  import java.lang.reflect.Modifier;
>>  import java.lang.reflect.Type;
>> +import java.math.BigInteger;
>>
>>  import org.apache.commons.math3.TestUtils;
>>  import org.apache.commons.math3.dfp.Dfp;
>>  import org.apache.commons.math3.dfp.DfpField;
>>  import org.apache.commons.math3.dfp.DfpMath;
>> +import org.apache.commons.math3.exception.MathArithmeticException;
>>  import org.apache.commons.math3.random.MersenneTwister;
>>  import org.apache.commons.math3.random.RandomGenerator;
>> +import org.apache.commons.math3.random.Well1024a;
>>  import org.junit.Assert;
>>  import org.junit.Before;
>>  import org.junit.Ignore;
>> @@ -958,13 +961,13 @@ public class FastMathTest {
>>      @Test
>>      public void testNextAfter() {
>>          // 0x402fffffffffffff 0x404123456789abcd -> 4030000000000000
>> -        Assert.assertEquals(16.0, FastMath.nextAfter(15.999999999999998, 34.27555555555555), 0.0);
>> +        Assert.assertEquals(16.0, FastMath.nextUp(15.999999999999998), 0.0);
>>
>>          // 0xc02fffffffffffff 0x404123456789abcd -> c02ffffffffffffe
>>          Assert.assertEquals(-15.999999999999996, FastMath.nextAfter(-15.999999999999998, 34.27555555555555), 0.0);
>>
>>          // 0x402fffffffffffff 0x400123456789abcd -> 402ffffffffffffe
>> -        Assert.assertEquals(15.999999999999996, FastMath.nextAfter(15.999999999999998, 2.142222222222222), 0.0);
>> +        Assert.assertEquals(15.999999999999996, FastMath.nextDown(15.999999999999998), 0.0);
>>
>>          // 0xc02fffffffffffff 0x400123456789abcd -> c02ffffffffffffe
>>          Assert.assertEquals(-15.999999999999996, FastMath.nextAfter(-15.999999999999998, 2.142222222222222), 0.0);
>> @@ -1037,8 +1040,8 @@ public class FastMathTest {
>>          Assert.assertEquals(-Float.MAX_VALUE,FastMath.nextAfter(Float.NEGATIVE_INFINITY, 0F), 0F);
>>          Assert.assertEquals(Float.MAX_VALUE,FastMath.nextAfter(Float.POSITIVE_INFINITY, 0F), 0F);
>>          Assert.assertEquals(Float.NaN,FastMath.nextAfter(Float.NaN, 0F), 0F);
>> -        Assert.assertEquals(Float.POSITIVE_INFINITY,FastMath.nextAfter(Float.MAX_VALUE, Float.POSITIVE_INFINITY), 0F);
>> -        Assert.assertEquals(Float.NEGATIVE_INFINITY,FastMath.nextAfter(-Float.MAX_VALUE, Float.NEGATIVE_INFINITY), 0F);
>> +        Assert.assertEquals(Float.POSITIVE_INFINITY,FastMath.nextUp(Float.MAX_VALUE), 0F);
>> +        Assert.assertEquals(Float.NEGATIVE_INFINITY,FastMath.nextDown(-Float.MAX_VALUE), 0F);
>>          Assert.assertEquals(Float.MIN_VALUE, FastMath.nextAfter(0F, 1F), 0F);
>>          Assert.assertEquals(-Float.MIN_VALUE, FastMath.nextAfter(0F, -1F), 0F);
>>          Assert.assertEquals(0F, FastMath.nextAfter(Float.MIN_VALUE, -1F), 0F);
>> @@ -1182,4 +1185,422 @@ public class FastMathTest {
>>          }
>>      }
>>
>> +    @Test
>> +    public void testIncrementExactInt() {
>> +        int[] specialValues = new int[] {
>> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
>> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
>> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
>> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
>> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
>> +        };
>> +        for (int a : specialValues) {
>> +            BigInteger bdA   = BigInteger.valueOf(a);
>> +            BigInteger bdSum = bdA.add(BigInteger.ONE);
>> +            if (bdSum.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
>> +                bdSum.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
>> +                try {
>> +                    FastMath.incrementExact(a);
>> +                    Assert.fail("an exception should have been thrown");
>> +                } catch (MathArithmeticException mae) {
>> +                    // expected
>> +                }
>> +            } else {
>> +                Assert.assertEquals(bdSum, BigInteger.valueOf(FastMath.incrementExact(a)));
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testDecrementExactInt() {
>> +        int[] specialValues = new int[] {
>> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
>> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
>> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
>> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
>> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
>> +        };
>> +        for (int a : specialValues) {
>> +            BigInteger bdA   = BigInteger.valueOf(a);
>> +            BigInteger bdSub = bdA.subtract(BigInteger.ONE);
>> +            if (bdSub.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
>> +                bdSub.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
>> +                try {
>> +                    FastMath.decrementExact(a);
>> +                    Assert.fail("an exception should have been thrown");
>> +                } catch (MathArithmeticException mae) {
>> +                    // expected
>> +                }
>> +            } else {
>> +                Assert.assertEquals(bdSub, BigInteger.valueOf(FastMath.decrementExact(a)));
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testAddExactInt() {
>> +        int[] specialValues = new int[] {
>> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
>> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
>> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
>> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
>> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
>> +        };
>> +        for (int a : specialValues) {
>> +            for (int b : specialValues) {
>> +                BigInteger bdA   = BigInteger.valueOf(a);
>> +                BigInteger bdB   = BigInteger.valueOf(b);
>> +                BigInteger bdSum = bdA.add(bdB);
>> +                if (bdSum.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
>> +                        bdSum.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
>> +                    try {
>> +                        FastMath.addExact(a, b);
>> +                        Assert.fail("an exception should have been thrown");
>> +                    } catch (MathArithmeticException mae) {
>> +                        // expected
>> +                    }
>> +                } else {
>> +                    Assert.assertEquals(bdSum, BigInteger.valueOf(FastMath.addExact(a, b)));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testAddExactLong() {
>> +        long[] specialValues = new long[] {
>> +            Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MIN_VALUE + 2,
>> +            Long.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE - 2,
>> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
>> +            -1 - (Long.MIN_VALUE / 2), 0 - (Long.MIN_VALUE / 2), 1 - (Long.MIN_VALUE / 2),
>> +            -1 + (Long.MAX_VALUE / 2), 0 + (Long.MAX_VALUE / 2), 1 + (Long.MAX_VALUE / 2),
>> +        };
>> +        for (long a : specialValues) {
>> +            for (long b : specialValues) {
>> +                BigInteger bdA   = BigInteger.valueOf(a);
>> +                BigInteger bdB   = BigInteger.valueOf(b);
>> +                BigInteger bdSum = bdA.add(bdB);
>> +                if (bdSum.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0 ||
>> +                        bdSum.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
>> +                    try {
>> +                        FastMath.addExact(a, b);
>> +                        Assert.fail("an exception should have been thrown");
>> +                    } catch (MathArithmeticException mae) {
>> +                        // expected
>> +                    }
>> +                } else {
>> +                    Assert.assertEquals(bdSum, BigInteger.valueOf(FastMath.addExact(a, b)));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testSubtractExactInt() {
>> +        int[] specialValues = new int[] {
>> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
>> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
>> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
>> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
>> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
>> +        };
>> +        for (int a : specialValues) {
>> +            for (int b : specialValues) {
>> +                BigInteger bdA   = BigInteger.valueOf(a);
>> +                BigInteger bdB   = BigInteger.valueOf(b);
>> +                BigInteger bdSub = bdA.subtract(bdB);
>> +                if (bdSub.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
>> +                        bdSub.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
>> +                    try {
>> +                        FastMath.subtractExact(a, b);
>> +                        Assert.fail("an exception should have been thrown");
>> +                    } catch (MathArithmeticException mae) {
>> +                        // expected
>> +                    }
>> +                } else {
>> +                    Assert.assertEquals(bdSub, BigInteger.valueOf(FastMath.subtractExact(a, b)));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testSubtractExactLong() {
>> +        long[] specialValues = new long[] {
>> +            Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MIN_VALUE + 2,
>> +            Long.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE - 2,
>> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
>> +            -1 - (Long.MIN_VALUE / 2), 0 - (Long.MIN_VALUE / 2), 1 - (Long.MIN_VALUE / 2),
>> +            -1 + (Long.MAX_VALUE / 2), 0 + (Long.MAX_VALUE / 2), 1 + (Long.MAX_VALUE / 2),
>> +        };
>> +        for (long a : specialValues) {
>> +            for (long b : specialValues) {
>> +                BigInteger bdA   = BigInteger.valueOf(a);
>> +                BigInteger bdB   = BigInteger.valueOf(b);
>> +                BigInteger bdSub = bdA.subtract(bdB);
>> +                if (bdSub.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0 ||
>> +                        bdSub.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
>> +                    try {
>> +                        FastMath.subtractExact(a, b);
>> +                        Assert.fail("an exception should have been thrown");
>> +                    } catch (MathArithmeticException mae) {
>> +                        // expected
>> +                    }
>> +                } else {
>> +                    Assert.assertEquals(bdSub, BigInteger.valueOf(FastMath.subtractExact(a, b)));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testMultiplyExactInt() {
>> +        int[] specialValues = new int[] {
>> +            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 2,
>> +            Integer.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 2,
>> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
>> +            -1 - (Integer.MIN_VALUE / 2), 0 - (Integer.MIN_VALUE / 2), 1 - (Integer.MIN_VALUE / 2),
>> +            -1 + (Integer.MAX_VALUE / 2), 0 + (Integer.MAX_VALUE / 2), 1 + (Integer.MAX_VALUE / 2),
>> +        };
>> +        for (int a : specialValues) {
>> +            for (int b : specialValues) {
>> +                BigInteger bdA   = BigInteger.valueOf(a);
>> +                BigInteger bdB   = BigInteger.valueOf(b);
>> +                BigInteger bdMul = bdA.multiply(bdB);
>> +                if (bdMul.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 ||
>> +                        bdMul.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
>> +                    try {
>> +                        FastMath.multiplyExact(a, b);
>> +                        Assert.fail("an exception should have been thrown " + a + b);
>> +                    } catch (MathArithmeticException mae) {
>> +                        // expected
>> +                    }
>> +                } else {
>> +                    Assert.assertEquals(bdMul, BigInteger.valueOf(FastMath.multiplyExact(a, b)));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testMultiplyExactLong() {
>> +        long[] specialValues = new long[] {
>> +            Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MIN_VALUE + 2,
>> +            Long.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE - 2,
>> +            -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
>> +            -1 - (Long.MIN_VALUE / 2), 0 - (Long.MIN_VALUE / 2), 1 - (Long.MIN_VALUE / 2),
>> +            -1 + (Long.MAX_VALUE / 2), 0 + (Long.MAX_VALUE / 2), 1 + (Long.MAX_VALUE / 2),
>> +        };
>> +        for (long a : specialValues) {
>> +            for (long b : specialValues) {
>> +                BigInteger bdA   = BigInteger.valueOf(a);
>> +                BigInteger bdB   = BigInteger.valueOf(b);
>> +                BigInteger bdMul = bdA.multiply(bdB);
>> +                if (bdMul.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0 ||
>> +                        bdMul.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
>> +                    try {
>> +                        FastMath.multiplyExact(a, b);
>> +                        Assert.fail("an exception should have been thrown " + a + b);
>> +                    } catch (MathArithmeticException mae) {
>> +                        // expected
>> +                    }
>> +                } else {
>> +                    Assert.assertEquals(bdMul, BigInteger.valueOf(FastMath.multiplyExact(a, b)));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test(expected=MathArithmeticException.class)
>> +    public void testToIntExactTooLow() {
>> +        FastMath.toIntExact(-1l + Integer.MIN_VALUE);
>> +    }
>> +
>> +    @Test(expected=MathArithmeticException.class)
>> +    public void testToIntExactTooHigh() {
>> +        FastMath.toIntExact(+1l + Integer.MAX_VALUE);
>> +    }
>> +
>> +    @Test
>> +    public void testToIntExact() {
>> +        for (int n = -1000; n < 1000; ++n) {
>> +            Assert.assertEquals(n, FastMath.toIntExact(0l + n));
>> +        }
>> +        Assert.assertEquals(Integer.MIN_VALUE, FastMath.toIntExact(0l + Integer.MIN_VALUE));
>> +        Assert.assertEquals(Integer.MAX_VALUE, FastMath.toIntExact(0l + Integer.MAX_VALUE));
>> +    }
>> +
>> +    @Test
>> +    public void testFloorDivInt() {
>> +        Assert.assertEquals(+1, FastMath.floorDiv(+4, +3));
>> +        Assert.assertEquals(-2, FastMath.floorDiv(-4, +3));
>> +        Assert.assertEquals(-2, FastMath.floorDiv(+4, -3));
>> +        Assert.assertEquals(+1, FastMath.floorDiv(-4, -3));
>> +        try {
>> +            FastMath.floorDiv(1, 0);
>> +            Assert.fail("an exception should have been thrown");
>> +        } catch (MathArithmeticException mae) {
>> +            // expected
>> +        }
>> +        for (int a = -100; a <= 100; ++a) {
>> +            for (int b = -100; b <= 100; ++b) {
>> +                if (b != 0) {
>> +                    Assert.assertEquals(poorManFloorDiv(a, b), FastMath.floorDiv(a, b));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testFloorModInt() {
>> +        Assert.assertEquals(+1, FastMath.floorMod(+4, +3));
>> +        Assert.assertEquals(+2, FastMath.floorMod(-4, +3));
>> +        Assert.assertEquals(-2, FastMath.floorMod(+4, -3));
>> +        Assert.assertEquals(-1, FastMath.floorMod(-4, -3));
>> +        try {
>> +            FastMath.floorMod(1, 0);
>> +            Assert.fail("an exception should have been thrown");
>> +        } catch (MathArithmeticException mae) {
>> +            // expected
>> +        }
>> +        for (int a = -100; a <= 100; ++a) {
>> +            for (int b = -100; b <= 100; ++b) {
>> +                if (b != 0) {
>> +                    Assert.assertEquals(poorManFloorMod(a, b), FastMath.floorMod(a, b));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testFloorDivModInt() {
>> +        RandomGenerator generator = new Well1024a(0x7ccab45edeaab90al);
>> +        for (int i = 0; i < 10000; ++i) {
>> +            int a = generator.nextInt();
>> +            int b = generator.nextInt();
>> +            if (b == 0) {
>> +                try {
>> +                    FastMath.floorDiv(a, b);
>> +                    Assert.fail("an exception should have been thrown");
>> +                } catch (MathArithmeticException mae) {
>> +                    // expected
>> +                }
>> +            } else {
>> +                int d = FastMath.floorDiv(a, b);
>> +                int m = FastMath.floorMod(a, b);
>> +                Assert.assertEquals(FastMath.toIntExact(poorManFloorDiv(a, b)), d);
>> +                Assert.assertEquals(FastMath.toIntExact(poorManFloorMod(a, b)), m);
>> +                Assert.assertEquals(a, d * b + m);
>> +                if (b < 0) {
>> +                    Assert.assertTrue(m <= 0);
>> +                    Assert.assertTrue(-m < -b);
>> +                } else {
>> +                    Assert.assertTrue(m >= 0);
>> +                    Assert.assertTrue(m < b);
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testFloorDivLong() {
>> +        Assert.assertEquals(+1l, FastMath.floorDiv(+4l, +3l));
>> +        Assert.assertEquals(-2l, FastMath.floorDiv(-4l, +3l));
>> +        Assert.assertEquals(-2l, FastMath.floorDiv(+4l, -3l));
>> +        Assert.assertEquals(+1l, FastMath.floorDiv(-4l, -3l));
>> +        try {
>> +            FastMath.floorDiv(1l, 0l);
>> +            Assert.fail("an exception should have been thrown");
>> +        } catch (MathArithmeticException mae) {
>> +            // expected
>> +        }
>> +        for (long a = -100l; a <= 100l; ++a) {
>> +            for (long b = -100l; b <= 100l; ++b) {
>> +                if (b != 0) {
>> +                    Assert.assertEquals(poorManFloorDiv(a, b), FastMath.floorDiv(a, b));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testFloorModLong() {
>> +        Assert.assertEquals(+1l, FastMath.floorMod(+4l, +3l));
>> +        Assert.assertEquals(+2l, FastMath.floorMod(-4l, +3l));
>> +        Assert.assertEquals(-2l, FastMath.floorMod(+4l, -3l));
>> +        Assert.assertEquals(-1l, FastMath.floorMod(-4l, -3l));
>> +        try {
>> +            FastMath.floorMod(1l, 0l);
>> +            Assert.fail("an exception should have been thrown");
>> +        } catch (MathArithmeticException mae) {
>> +            // expected
>> +        }
>> +        for (long a = -100l; a <= 100l; ++a) {
>> +            for (long b = -100l; b <= 100l; ++b) {
>> +                if (b != 0) {
>> +                    Assert.assertEquals(poorManFloorMod(a, b), FastMath.floorMod(a, b));
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    @Test
>> +    public void testFloorDivModLong() {
>> +        RandomGenerator generator = new Well1024a(0xb87b9bc14c96ccd5l);
>> +        for (int i = 0; i < 10000; ++i) {
>> +            long a = generator.nextLong();
>> +            long b = generator.nextLong();
>> +            if (b == 0) {
>> +                try {
>> +                    FastMath.floorDiv(a, b);
>> +                    Assert.fail("an exception should have been thrown");
>> +                } catch (MathArithmeticException mae) {
>> +                    // expected
>> +                }
>> +            } else {
>> +                long d = FastMath.floorDiv(a, b);
>> +                long m = FastMath.floorMod(a, b);
>> +                Assert.assertEquals(poorManFloorDiv(a, b), d);
>> +                Assert.assertEquals(poorManFloorMod(a, b), m);
>> +                Assert.assertEquals(a, d * b + m);
>> +                if (b < 0) {
>> +                    Assert.assertTrue(m <= 0);
>> +                    Assert.assertTrue(-m < -b);
>> +                } else {
>> +                    Assert.assertTrue(m >= 0);
>> +                    Assert.assertTrue(m < b);
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    private long poorManFloorDiv(long a, long b) {
>> +
>> +        // find q0, r0 such that a = q0 b + r0
>> +        BigInteger q0 = BigInteger.valueOf(a / b);
>> +        BigInteger r0 = BigInteger.valueOf(a % b);
>> +        BigInteger fd = BigInteger.valueOf(Integer.MIN_VALUE);
>> +        BigInteger bigB = BigInteger.valueOf(b);
>> +
>> +        for (int k = -2; k < 2; ++k) {
>> +            // find another pair q, r such that a = q b + r
>> +            BigInteger bigK = BigInteger.valueOf(k);
>> +            BigInteger q = q0.subtract(bigK);
>> +            BigInteger r = r0.add(bigK.multiply(bigB));
>> +            if (r.abs().compareTo(bigB.abs()) < 0 &&
>> +                (r.longValue() == 0l || ((r.longValue() ^ b) & 0x8000000000000000l) == 0)) {
>> +                if (fd.compareTo(q) < 0) {
>> +                    fd = q;
>> +                }
>> +            }
>> +        }
>> +
>> +        return fd.longValue();
>> +
>> +    }
>> +
>> +    private long poorManFloorMod(long a, long b) {
>> +        return a - b * poorManFloorDiv(a, b);
>> +    }
>> +
>>  }
>>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org