You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ra...@apache.org on 2017/01/28 12:44:26 UTC
[4/5] commons-numbers git commit: Create structure for fraction
module within commons-numbers. Add dependencyManagement to parent pom.xml for
uniform dependency on numbers core;
remove version from references to numbers-core in child modules. Add test ja
Create structure for fraction module within commons-numbers.
Add dependencyManagement to parent pom.xml for uniform dependency on numbers core; remove version from references to numbers-core in child modules.
Add test jar to numbers core pom.xml to allow for re-use of TestUtils.
Add ArithmeticUtils from commons-math since Fraction, BigFraction heavily depends on it.
Project: http://git-wip-us.apache.org/repos/asf/commons-numbers/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-numbers/commit/aaef6f7a
Tree: http://git-wip-us.apache.org/repos/asf/commons-numbers/tree/aaef6f7a
Diff: http://git-wip-us.apache.org/repos/asf/commons-numbers/diff/aaef6f7a
Branch: refs/heads/multimodule
Commit: aaef6f7aa74da893b018ec3debe4367de3243c48
Parents: b026db1
Author: Ray DeCampo <ra...@decampo.org>
Authored: Sun Jan 22 20:41:30 2017 -0500
Committer: Ray DeCampo <ra...@decampo.org>
Committed: Sun Jan 22 20:41:30 2017 -0500
----------------------------------------------------------------------
commons-numbers-complex/pom.xml | 1 -
commons-numbers-core/pom.xml | 15 +
.../commons/numbers/core/ArithmeticUtils.java | 772 +++++++++++
.../core/NumbersArithmeticException.java | 54 +
.../numbers/core/ArithmeticUtilsTest.java | 782 ++++++++++++
commons-numbers-fraction/LICENSE.txt | 201 +++
commons-numbers-fraction/NOTICE.txt | 6 +
commons-numbers-fraction/README.md | 98 ++
commons-numbers-fraction/pom.xml | 58 +
.../numbers/fraction/AbstractFormat.java | 206 +++
.../commons/numbers/fraction/BigFraction.java | 1199 ++++++++++++++++++
.../numbers/fraction/BigFractionField.java | 83 ++
.../numbers/fraction/BigFractionFormat.java | 283 +++++
.../commons/numbers/fraction/Fraction.java | 664 ++++++++++
.../fraction/FractionConversionException.java | 51 +
.../numbers/fraction/FractionException.java | 44 +
.../commons/numbers/fraction/FractionField.java | 82 ++
.../numbers/fraction/FractionFormat.java | 261 ++++
.../fraction/FractionOverflowException.java | 47 +
.../fraction/FractionParseException.java | 38 +
.../fraction/ProperBigFractionFormat.java | 235 ++++
.../numbers/fraction/ProperFractionFormat.java | 227 ++++
.../fraction/ZeroDenominatorException.java | 53 +
.../commons/numbers/fraction/package-info.java | 22 +
.../numbers/fraction/BigFractionFieldTest.java | 43 +
.../numbers/fraction/BigFractionFormatTest.java | 330 +++++
.../numbers/fraction/BigFractionTest.java | 635 ++++++++++
.../numbers/fraction/FractionFieldTest.java | 43 +
.../numbers/fraction/FractionFormatTest.java | 349 +++++
.../commons/numbers/fraction/FractionTest.java | 625 +++++++++
commons-numbers-quaternion/pom.xml | 1 -
pom.xml | 20 +-
32 files changed, 7525 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/aaef6f7a/commons-numbers-complex/pom.xml
----------------------------------------------------------------------
diff --git a/commons-numbers-complex/pom.xml b/commons-numbers-complex/pom.xml
index 735348f..3fec4ba 100644
--- a/commons-numbers-complex/pom.xml
+++ b/commons-numbers-complex/pom.xml
@@ -46,7 +46,6 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-numbers-core</artifactId>
- <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/aaef6f7a/commons-numbers-core/pom.xml
----------------------------------------------------------------------
diff --git a/commons-numbers-core/pom.xml b/commons-numbers-core/pom.xml
index 39dbdcb..76c2512 100644
--- a/commons-numbers-core/pom.xml
+++ b/commons-numbers-core/pom.xml
@@ -42,5 +42,20 @@
<numbers.parent.dir>${basedir}/..</numbers.parent.dir>
</properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/aaef6f7a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/ArithmeticUtils.java
----------------------------------------------------------------------
diff --git a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/ArithmeticUtils.java b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/ArithmeticUtils.java
new file mode 100644
index 0000000..343d24b
--- /dev/null
+++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/ArithmeticUtils.java
@@ -0,0 +1,772 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.numbers.core;
+
+import java.math.BigInteger;
+
+/**
+ * Some useful, arithmetics related, additions to the built-in functions in
+ * {@link Math}.
+ *
+ */
+public final class ArithmeticUtils {
+
+ /** Private constructor. */
+ private ArithmeticUtils() {
+ super();
+ }
+
+ /**
+ * Add two integers, checking for overflow.
+ *
+ * @param x an addend
+ * @param y an addend
+ * @return the sum {@code x+y}
+ * @throws NumbersArithmeticException if the result can not be represented
+ * as an {@code int}.
+ * @since 1.1
+ */
+ public static int addAndCheck(int x, int y)
+ throws NumbersArithmeticException {
+ long s = (long)x + (long)y;
+ if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) {
+ throw new NumbersArithmeticException("overflow in addition: {0} + {1}", x, y);
+ }
+ return (int)s;
+ }
+
+ /**
+ * Add two long integers, checking for overflow.
+ *
+ * @param a an addend
+ * @param b an addend
+ * @return the sum {@code a+b}
+ * @throws NumbersArithmeticException if the result can not be represented as an long
+ * @since 1.2
+ */
+ public static long addAndCheck(long a, long b) throws NumbersArithmeticException {
+ return addAndCheck(a, b, "overflow in addition: {0} + {1}");
+ }
+
+ /**
+ * Computes the greatest common divisor of the absolute value of two
+ * numbers, using a modified version of the "binary gcd" method.
+ * See Knuth 4.5.2 algorithm B.
+ * The algorithm is due to Josef Stein (1961).
+ * <br>
+ * Special cases:
+ * <ul>
+ * <li>The invocations
+ * {@code gcd(Integer.MIN_VALUE, Integer.MIN_VALUE)},
+ * {@code gcd(Integer.MIN_VALUE, 0)} and
+ * {@code gcd(0, Integer.MIN_VALUE)} throw an
+ * {@code ArithmeticException}, because the result would be 2^31, which
+ * is too large for an int value.</li>
+ * <li>The result of {@code gcd(x, x)}, {@code gcd(0, x)} and
+ * {@code gcd(x, 0)} is the absolute value of {@code x}, except
+ * for the special cases above.</li>
+ * <li>The invocation {@code gcd(0, 0)} is the only one which returns
+ * {@code 0}.</li>
+ * </ul>
+ *
+ * @param p Number.
+ * @param q Number.
+ * @return the greatest common divisor (never negative).
+ * @throws NumbersArithmeticException if the result cannot be represented as
+ * a non-negative {@code int} value.
+ * @since 1.1
+ */
+ public static int gcd(int p, int q) throws NumbersArithmeticException {
+ int a = p;
+ int b = q;
+ if (a == 0 ||
+ b == 0) {
+ if (a == Integer.MIN_VALUE ||
+ b == Integer.MIN_VALUE) {
+ throw new NumbersArithmeticException("overflow: gcd({0}, {1}) is 2^31",
+ p, q);
+ }
+ return Math.abs(a + b);
+ }
+
+ long al = a;
+ long bl = b;
+ boolean useLong = false;
+ if (a < 0) {
+ if(Integer.MIN_VALUE == a) {
+ useLong = true;
+ } else {
+ a = -a;
+ }
+ al = -al;
+ }
+ if (b < 0) {
+ if (Integer.MIN_VALUE == b) {
+ useLong = true;
+ } else {
+ b = -b;
+ }
+ bl = -bl;
+ }
+ if (useLong) {
+ if(al == bl) {
+ throw new NumbersArithmeticException("overflow: gcd({0}, {1}) is 2^31",
+ p, q);
+ }
+ long blbu = bl;
+ bl = al;
+ al = blbu % al;
+ if (al == 0) {
+ if (bl > Integer.MAX_VALUE) {
+ throw new NumbersArithmeticException("overflow: gcd({0}, {1}) is 2^31",
+ p, q);
+ }
+ return (int) bl;
+ }
+ blbu = bl;
+
+ // Now "al" and "bl" fit in an "int".
+ b = (int) al;
+ a = (int) (blbu % al);
+ }
+
+ return gcdPositive(a, b);
+ }
+
+ /**
+ * Computes the greatest common divisor of two <em>positive</em> numbers
+ * (this precondition is <em>not</em> checked and the result is undefined
+ * if not fulfilled) using the "binary gcd" method which avoids division
+ * and modulo operations.
+ * See Knuth 4.5.2 algorithm B.
+ * The algorithm is due to Josef Stein (1961).
+ * <br/>
+ * Special cases:
+ * <ul>
+ * <li>The result of {@code gcd(x, x)}, {@code gcd(0, x)} and
+ * {@code gcd(x, 0)} is the value of {@code x}.</li>
+ * <li>The invocation {@code gcd(0, 0)} is the only one which returns
+ * {@code 0}.</li>
+ * </ul>
+ *
+ * @param a Positive number.
+ * @param b Positive number.
+ * @return the greatest common divisor.
+ */
+ private static int gcdPositive(int a, int b) {
+ if (a == 0) {
+ return b;
+ }
+ else if (b == 0) {
+ return a;
+ }
+
+ // Make "a" and "b" odd, keeping track of common power of 2.
+ final int aTwos = Integer.numberOfTrailingZeros(a);
+ a >>= aTwos;
+ final int bTwos = Integer.numberOfTrailingZeros(b);
+ b >>= bTwos;
+ final int shift = Math.min(aTwos, bTwos);
+
+ // "a" and "b" are positive.
+ // If a > b then "gdc(a, b)" is equal to "gcd(a - b, b)".
+ // If a < b then "gcd(a, b)" is equal to "gcd(b - a, a)".
+ // Hence, in the successive iterations:
+ // "a" becomes the absolute difference of the current values,
+ // "b" becomes the minimum of the current values.
+ while (a != b) {
+ final int delta = a - b;
+ b = Math.min(a, b);
+ a = Math.abs(delta);
+
+ // Remove any power of 2 in "a" ("b" is guaranteed to be odd).
+ a >>= Integer.numberOfTrailingZeros(a);
+ }
+
+ // Recover the common power of 2.
+ return a << shift;
+ }
+
+ /**
+ * <p>
+ * Gets the greatest common divisor of the absolute value of two numbers,
+ * using the "binary gcd" method which avoids division and modulo
+ * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef
+ * Stein (1961).
+ * </p>
+ * Special cases:
+ * <ul>
+ * <li>The invocations
+ * {@code gcd(Long.MIN_VALUE, Long.MIN_VALUE)},
+ * {@code gcd(Long.MIN_VALUE, 0L)} and
+ * {@code gcd(0L, Long.MIN_VALUE)} throw an
+ * {@code ArithmeticException}, because the result would be 2^63, which
+ * is too large for a long value.</li>
+ * <li>The result of {@code gcd(x, x)}, {@code gcd(0L, x)} and
+ * {@code gcd(x, 0L)} is the absolute value of {@code x}, except
+ * for the special cases above.
+ * <li>The invocation {@code gcd(0L, 0L)} is the only one which returns
+ * {@code 0L}.</li>
+ * </ul>
+ *
+ * @param p Number.
+ * @param q Number.
+ * @return the greatest common divisor, never negative.
+ * @throws NumbersArithmeticException if the result cannot be represented as
+ * a non-negative {@code long} value.
+ * @since 2.1
+ */
+ public static long gcd(final long p, final long q) throws NumbersArithmeticException {
+ long u = p;
+ long v = q;
+ if ((u == 0) || (v == 0)) {
+ if ((u == Long.MIN_VALUE) || (v == Long.MIN_VALUE)){
+ throw new NumbersArithmeticException("overflow: gcd({0}, {1}) is 2^63",
+ p, q);
+ }
+ return Math.abs(u) + Math.abs(v);
+ }
+ // keep u and v negative, as negative integers range down to
+ // -2^63, while positive numbers can only be as large as 2^63-1
+ // (i.e. we can't necessarily negate a negative number without
+ // overflow)
+ /* assert u!=0 && v!=0; */
+ if (u > 0) {
+ u = -u;
+ } // make u negative
+ if (v > 0) {
+ v = -v;
+ } // make v negative
+ // B1. [Find power of 2]
+ int k = 0;
+ while ((u & 1) == 0 && (v & 1) == 0 && k < 63) { // while u and v are
+ // both even...
+ u /= 2;
+ v /= 2;
+ k++; // cast out twos.
+ }
+ if (k == 63) {
+ throw new NumbersArithmeticException("overflow: gcd({0}, {1}) is 2^63",
+ p, q);
+ }
+ // B2. Initialize: u and v have been divided by 2^k and at least
+ // one is odd.
+ long t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */;
+ // t negative: u was odd, v may be even (t replaces v)
+ // t positive: u was even, v is odd (t replaces u)
+ do {
+ /* assert u<0 && v<0; */
+ // B4/B3: cast out twos from t.
+ while ((t & 1) == 0) { // while t is even..
+ t /= 2; // cast out twos
+ }
+ // B5 [reset max(u,v)]
+ if (t > 0) {
+ u = -t;
+ } else {
+ v = t;
+ }
+ // B6/B3. at this point both u and v should be odd.
+ t = (v - u) / 2;
+ // |u| larger: t positive (replace u)
+ // |v| larger: t negative (replace v)
+ } while (t != 0);
+ return -u * (1L << k); // gcd is u*2^k
+ }
+
+ /**
+ * <p>
+ * Returns the least common multiple of the absolute value of two numbers,
+ * using the formula {@code lcm(a,b) = (a / gcd(a,b)) * b}.
+ * </p>
+ * Special cases:
+ * <ul>
+ * <li>The invocations {@code lcm(Integer.MIN_VALUE, n)} and
+ * {@code lcm(n, Integer.MIN_VALUE)}, where {@code abs(n)} is a
+ * power of 2, throw an {@code ArithmeticException}, because the result
+ * would be 2^31, which is too large for an int value.</li>
+ * <li>The result of {@code lcm(0, x)} and {@code lcm(x, 0)} is
+ * {@code 0} for any {@code x}.
+ * </ul>
+ *
+ * @param a Number.
+ * @param b Number.
+ * @return the least common multiple, never negative.
+ * @throws NumbersArithmeticException if the result cannot be represented as
+ * a non-negative {@code int} value.
+ * @since 1.1
+ */
+ public static int lcm(int a, int b) throws NumbersArithmeticException {
+ if (a == 0 || b == 0){
+ return 0;
+ }
+ int lcm = Math.abs(ArithmeticUtils.mulAndCheck(a / gcd(a, b), b));
+ if (lcm == Integer.MIN_VALUE) {
+ throw new NumbersArithmeticException("overflow: lcm({0}, {1}) is 2^31",
+ a, b);
+ }
+ return lcm;
+ }
+
+ /**
+ * <p>
+ * Returns the least common multiple of the absolute value of two numbers,
+ * using the formula {@code lcm(a,b) = (a / gcd(a,b)) * b}.
+ * </p>
+ * Special cases:
+ * <ul>
+ * <li>The invocations {@code lcm(Long.MIN_VALUE, n)} and
+ * {@code lcm(n, Long.MIN_VALUE)}, where {@code abs(n)} is a
+ * power of 2, throw an {@code ArithmeticException}, because the result
+ * would be 2^63, which is too large for an int value.</li>
+ * <li>The result of {@code lcm(0L, x)} and {@code lcm(x, 0L)} is
+ * {@code 0L} for any {@code x}.
+ * </ul>
+ *
+ * @param a Number.
+ * @param b Number.
+ * @return the least common multiple, never negative.
+ * @throws NumbersArithmeticException if the result cannot be represented
+ * as a non-negative {@code long} value.
+ * @since 2.1
+ */
+ public static long lcm(long a, long b) throws NumbersArithmeticException {
+ if (a == 0 || b == 0){
+ return 0;
+ }
+ long lcm = Math.abs(ArithmeticUtils.mulAndCheck(a / gcd(a, b), b));
+ if (lcm == Long.MIN_VALUE){
+ throw new NumbersArithmeticException("overflow: lcm({0}, {1}) is 2^63",
+ a, b);
+ }
+ return lcm;
+ }
+
+ /**
+ * Multiply two integers, checking for overflow.
+ *
+ * @param x Factor.
+ * @param y Factor.
+ * @return the product {@code x * y}.
+ * @throws NumbersArithmeticException if the result can not be
+ * represented as an {@code int}.
+ * @since 1.1
+ */
+ public static int mulAndCheck(int x, int y) throws NumbersArithmeticException {
+ long m = ((long)x) * ((long)y);
+ if (m < Integer.MIN_VALUE || m > Integer.MAX_VALUE) {
+ throw new NumbersArithmeticException();
+ }
+ return (int)m;
+ }
+
+ /**
+ * Multiply two long integers, checking for overflow.
+ *
+ * @param a Factor.
+ * @param b Factor.
+ * @return the product {@code a * b}.
+ * @throws NumbersArithmeticException if the result can not be represented
+ * as a {@code long}.
+ * @since 1.2
+ */
+ public static long mulAndCheck(long a, long b) throws NumbersArithmeticException {
+ long ret;
+ if (a > b) {
+ // use symmetry to reduce boundary cases
+ ret = mulAndCheck(b, a);
+ } else {
+ if (a < 0) {
+ if (b < 0) {
+ // check for positive overflow with negative a, negative b
+ if (a >= Long.MAX_VALUE / b) {
+ ret = a * b;
+ } else {
+ throw new NumbersArithmeticException();
+ }
+ } else if (b > 0) {
+ // check for negative overflow with negative a, positive b
+ if (Long.MIN_VALUE / b <= a) {
+ ret = a * b;
+ } else {
+ throw new NumbersArithmeticException();
+
+ }
+ } else {
+ // assert b == 0
+ ret = 0;
+ }
+ } else if (a > 0) {
+ // assert a > 0
+ // assert b > 0
+
+ // check for positive overflow with positive a, positive b
+ if (a <= Long.MAX_VALUE / b) {
+ ret = a * b;
+ } else {
+ throw new NumbersArithmeticException();
+ }
+ } else {
+ // assert a == 0
+ ret = 0;
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Subtract two integers, checking for overflow.
+ *
+ * @param x Minuend.
+ * @param y Subtrahend.
+ * @return the difference {@code x - y}.
+ * @throws NumbersArithmeticException if the result can not be represented
+ * as an {@code int}.
+ * @since 1.1
+ */
+ public static int subAndCheck(int x, int y) throws NumbersArithmeticException {
+ long s = (long)x - (long)y;
+ if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) {
+ throw new NumbersArithmeticException("overflow in subtraction: {0} - {1}", x, y);
+ }
+ return (int)s;
+ }
+
+ /**
+ * Subtract two long integers, checking for overflow.
+ *
+ * @param a Value.
+ * @param b Value.
+ * @return the difference {@code a - b}.
+ * @throws NumbersArithmeticException if the result can not be represented as a
+ * {@code long}.
+ * @since 1.2
+ */
+ public static long subAndCheck(long a, long b) throws NumbersArithmeticException {
+ long ret;
+ if (b == Long.MIN_VALUE) {
+ if (a < 0) {
+ ret = a - b;
+ } else {
+ throw new NumbersArithmeticException("overflow in subtraction: {0} + {1}", a, -b);
+ }
+ } else {
+ // use additive inverse
+ ret = addAndCheck(a, -b, "overflow in subtraction: {0} + {1}");
+ }
+ return ret;
+ }
+
+ /**
+ * Raise an int to an int power.
+ *
+ * @param k Number to raise.
+ * @param e Exponent (must be positive or zero).
+ * @return \( k^e \)
+ * @throws IllegalArgumentException if {@code e < 0}.
+ * @throws NumbersArithmeticException if the result would overflow.
+ */
+ public static int pow(final int k,
+ final int e)
+ throws NumbersArithmeticException {
+ if (e < 0) {
+ throw new IllegalArgumentException("negative exponent ({" + e + "})");
+ }
+
+ int exp = e;
+ int result = 1;
+ int k2p = k;
+ while (true) {
+ if ((exp & 0x1) != 0) {
+ result = mulAndCheck(result, k2p);
+ }
+
+ exp >>= 1;
+ if (exp == 0) {
+ break;
+ }
+
+ k2p = mulAndCheck(k2p, k2p);
+ }
+
+ return result;
+ }
+
+ /**
+ * Raise a long to an int power.
+ *
+ * @param k Number to raise.
+ * @param e Exponent (must be positive or zero).
+ * @return \( k^e \)
+ * @throws IllegalArgumentException if {@code e < 0}.
+ * @throws NumbersArithmeticException if the result would overflow.
+ */
+ public static long pow(final long k,
+ final int e)
+ throws NumbersArithmeticException {
+ if (e < 0) {
+ throw new IllegalArgumentException("negative exponent ({" + e + "})");
+ }
+
+ int exp = e;
+ long result = 1;
+ long k2p = k;
+ while (true) {
+ if ((exp & 0x1) != 0) {
+ result = mulAndCheck(result, k2p);
+ }
+
+ exp >>= 1;
+ if (exp == 0) {
+ break;
+ }
+
+ k2p = mulAndCheck(k2p, k2p);
+ }
+
+ return result;
+ }
+
+ /**
+ * Raise a BigInteger to an int power.
+ *
+ * @param k Number to raise.
+ * @param e Exponent (must be positive or zero).
+ * @return k<sup>e</sup>
+ * @throws IllegalArgumentException if {@code e < 0}.
+ */
+ public static BigInteger pow(final BigInteger k, int e) {
+ if (e < 0) {
+ throw new IllegalArgumentException("negative exponent ({" + e + "})");
+ }
+
+ return k.pow(e);
+ }
+
+ /**
+ * Raise a BigInteger to a long power.
+ *
+ * @param k Number to raise.
+ * @param e Exponent (must be positive or zero).
+ * @return k<sup>e</sup>
+ * @throws IllegalArgumentException if {@code e < 0}.
+ */
+ public static BigInteger pow(final BigInteger k, long e) {
+ if (e < 0) {
+ throw new IllegalArgumentException("negative exponent ({" + e + "})");
+ }
+
+ BigInteger result = BigInteger.ONE;
+ BigInteger k2p = k;
+ while (e != 0) {
+ if ((e & 0x1) != 0) {
+ result = result.multiply(k2p);
+ }
+ k2p = k2p.multiply(k2p);
+ e >>= 1;
+ }
+
+ return result;
+
+ }
+
+ /**
+ * Raise a BigInteger to a BigInteger power.
+ *
+ * @param k Number to raise.
+ * @param e Exponent (must be positive or zero).
+ * @return k<sup>e</sup>
+ * @throws IllegalArgumentException if {@code e < 0}.
+ */
+ public static BigInteger pow(final BigInteger k, BigInteger e) {
+ if (e.compareTo(BigInteger.ZERO) < 0) {
+ throw new IllegalArgumentException("negative exponent ({" + e + "})");
+ }
+
+ BigInteger result = BigInteger.ONE;
+ BigInteger k2p = k;
+ while (!BigInteger.ZERO.equals(e)) {
+ if (e.testBit(0)) {
+ result = result.multiply(k2p);
+ }
+ k2p = k2p.multiply(k2p);
+ e = e.shiftRight(1);
+ }
+
+ return result;
+ }
+
+ /**
+ * Add two long integers, checking for overflow.
+ *
+ * @param a Addend.
+ * @param b Addend.
+ * @param pattern Pattern to use for any thrown exception.
+ * @return the sum {@code a + b}.
+ * @throws NumbersArithmeticException if the result cannot be represented
+ * as a {@code long}.
+ * @since 1.2
+ */
+ private static long addAndCheck(long a, long b, String message) throws NumbersArithmeticException {
+ final long result = a + b;
+ if (!((a ^ b) < 0 || (a ^ result) >= 0)) {
+ throw new NumbersArithmeticException(message, a, b);
+ }
+ return result;
+ }
+
+ /**
+ * Returns true if the argument is a power of two.
+ *
+ * @param n the number to test
+ * @return true if the argument is a power of two
+ */
+ public static boolean isPowerOfTwo(long n) {
+ return (n > 0) && ((n & (n - 1)) == 0);
+ }
+
+ /**
+ * Returns the unsigned remainder from dividing the first argument
+ * by the second where each argument and the result is interpreted
+ * as an unsigned value.
+ * <p>This method does not use the {@code long} datatype.</p>
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned remainder of the first argument divided by
+ * the second argument.
+ *
+ * @since 4.0
+ */
+ public static int remainderUnsigned(int dividend, int divisor) {
+ if (divisor >= 0) {
+ if (dividend >= 0) {
+ return dividend % divisor;
+ }
+ // The implementation is a Java port of algorithm described in the book
+ // "Hacker's Delight" (section "Unsigned short division from signed division").
+ int q = ((dividend >>> 1) / divisor) << 1;
+ dividend -= q * divisor;
+ if (dividend < 0 || dividend >= divisor) {
+ dividend -= divisor;
+ }
+ return dividend;
+ }
+ return dividend >= 0 || dividend < divisor ? dividend : dividend - divisor;
+ }
+
+ /**
+ * Returns the unsigned remainder from dividing the first argument
+ * by the second where each argument and the result is interpreted
+ * as an unsigned value.
+ * <p>This method does not use the {@code BigInteger} datatype.</p>
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned remainder of the first argument divided by
+ * the second argument.
+ *
+ * @since 4.0
+ */
+ public static long remainderUnsigned(long dividend, long divisor) {
+ if (divisor >= 0L) {
+ if (dividend >= 0L) {
+ return dividend % divisor;
+ }
+ // The implementation is a Java port of algorithm described in the book
+ // "Hacker's Delight" (section "Unsigned short division from signed division").
+ long q = ((dividend >>> 1) / divisor) << 1;
+ dividend -= q * divisor;
+ if (dividend < 0L || dividend >= divisor) {
+ dividend -= divisor;
+ }
+ return dividend;
+ }
+ return dividend >= 0L || dividend < divisor ? dividend : dividend - divisor;
+ }
+
+ /**
+ * Returns the unsigned quotient of dividing the first argument by
+ * the second where each argument and the result is interpreted as
+ * an unsigned value.
+ * <p>Note that in two's complement arithmetic, the three other
+ * basic arithmetic operations of add, subtract, and multiply are
+ * bit-wise identical if the two operands are regarded as both
+ * being signed or both being unsigned. Therefore separate {@code
+ * addUnsigned}, etc. methods are not provided.</p>
+ * <p>This method does not use the {@code long} datatype.</p>
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned quotient of the first argument divided by
+ * the second argument
+ *
+ * @since 4.0
+ */
+ public static int divideUnsigned(int dividend, int divisor) {
+ if (divisor >= 0) {
+ if (dividend >= 0) {
+ return dividend / divisor;
+ }
+ // The implementation is a Java port of algorithm described in the book
+ // "Hacker's Delight" (section "Unsigned short division from signed division").
+ int q = ((dividend >>> 1) / divisor) << 1;
+ dividend -= q * divisor;
+ if (dividend < 0L || dividend >= divisor) {
+ q++;
+ }
+ return q;
+ }
+ return dividend >= 0 || dividend < divisor ? 0 : 1;
+ }
+
+ /**
+ * Returns the unsigned quotient of dividing the first argument by
+ * the second where each argument and the result is interpreted as
+ * an unsigned value.
+ * <p>Note that in two's complement arithmetic, the three other
+ * basic arithmetic operations of add, subtract, and multiply are
+ * bit-wise identical if the two operands are regarded as both
+ * being signed or both being unsigned. Therefore separate {@code
+ * addUnsigned}, etc. methods are not provided.</p>
+ * <p>This method does not use the {@code BigInteger} datatype.</p>
+ *
+ * @param dividend the value to be divided
+ * @param divisor the value doing the dividing
+ * @return the unsigned quotient of the first argument divided by
+ * the second argument.
+ *
+ * @since 4.0
+ */
+ public static long divideUnsigned(long dividend, long divisor) {
+ if (divisor >= 0L) {
+ if (dividend >= 0L) {
+ return dividend / divisor;
+ }
+ // The implementation is a Java port of algorithm described in the book
+ // "Hacker's Delight" (section "Unsigned short division from signed division").
+ long q = ((dividend >>> 1) / divisor) << 1;
+ dividend -= q * divisor;
+ if (dividend < 0L || dividend >= divisor) {
+ q++;
+ }
+ return q;
+ }
+ return dividend >= 0L || dividend < divisor ? 0L : 1L;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/aaef6f7a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/NumbersArithmeticException.java
----------------------------------------------------------------------
diff --git a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/NumbersArithmeticException.java b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/NumbersArithmeticException.java
new file mode 100644
index 0000000..a910e80
--- /dev/null
+++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/NumbersArithmeticException.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.numbers.core;
+
+import java.text.MessageFormat;
+
+/**
+ * Base class for arithmetic exceptions.
+ */
+public class NumbersArithmeticException extends ArithmeticException {
+ /** Serializable version Id. */
+ private static final long serialVersionUID = -6024911025449780474L;
+
+ private final Object[] formatArguments;
+
+ /**
+ * Default constructor.
+ */
+ public NumbersArithmeticException() {
+ this("arithmetic exception");
+ }
+
+ /**
+ * Constructor with a specific message.
+ *
+ * @param message Message pattern providing the specific context of
+ * the error.
+ * @param args Arguments.
+ */
+ public NumbersArithmeticException(String message, Object ... args) {
+ super(message);
+ this.formatArguments = args;
+ }
+
+ @Override
+ public String getMessage() {
+ return MessageFormat.format(super.getMessage(), formatArguments);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/aaef6f7a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/ArithmeticUtilsTest.java
----------------------------------------------------------------------
diff --git a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/ArithmeticUtilsTest.java b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/ArithmeticUtilsTest.java
new file mode 100644
index 0000000..500aca3
--- /dev/null
+++ b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/ArithmeticUtilsTest.java
@@ -0,0 +1,782 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.numbers.core;
+
+import java.util.Arrays;
+import java.math.BigInteger;
+import java.util.Collections;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test cases for the {@link ArithmeticUtils} class.
+ *
+ */
+public class ArithmeticUtilsTest {
+
+ @Test
+ public void testAddAndCheck() {
+ int big = Integer.MAX_VALUE;
+ int bigNeg = Integer.MIN_VALUE;
+ Assert.assertEquals(big, ArithmeticUtils.addAndCheck(big, 0));
+ try {
+ ArithmeticUtils.addAndCheck(big, 1);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ }
+ try {
+ ArithmeticUtils.addAndCheck(bigNeg, -1);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ }
+ }
+
+ @Test
+ public void testAddAndCheckLong() {
+ long max = Long.MAX_VALUE;
+ long min = Long.MIN_VALUE;
+ Assert.assertEquals(max, ArithmeticUtils.addAndCheck(max, 0L));
+ Assert.assertEquals(min, ArithmeticUtils.addAndCheck(min, 0L));
+ Assert.assertEquals(max, ArithmeticUtils.addAndCheck(0L, max));
+ Assert.assertEquals(min, ArithmeticUtils.addAndCheck(0L, min));
+ Assert.assertEquals(1, ArithmeticUtils.addAndCheck(-1L, 2L));
+ Assert.assertEquals(1, ArithmeticUtils.addAndCheck(2L, -1L));
+ Assert.assertEquals(-3, ArithmeticUtils.addAndCheck(-2L, -1L));
+ Assert.assertEquals(min, ArithmeticUtils.addAndCheck(min + 1, -1L));
+ Assert.assertEquals(-1, ArithmeticUtils.addAndCheck(min, max));
+ testAddAndCheckLongFailure(max, 1L);
+ testAddAndCheckLongFailure(min, -1L);
+ testAddAndCheckLongFailure(1L, max);
+ testAddAndCheckLongFailure(-1L, min);
+ testAddAndCheckLongFailure(max, max);
+ testAddAndCheckLongFailure(min, min);
+ }
+
+ @Test
+ public void testGcd() {
+ int a = 30;
+ int b = 50;
+ int c = 77;
+
+ Assert.assertEquals(0, ArithmeticUtils.gcd(0, 0));
+
+ Assert.assertEquals(b, ArithmeticUtils.gcd(0, b));
+ Assert.assertEquals(a, ArithmeticUtils.gcd(a, 0));
+ Assert.assertEquals(b, ArithmeticUtils.gcd(0, -b));
+ Assert.assertEquals(a, ArithmeticUtils.gcd(-a, 0));
+
+ Assert.assertEquals(10, ArithmeticUtils.gcd(a, b));
+ Assert.assertEquals(10, ArithmeticUtils.gcd(-a, b));
+ Assert.assertEquals(10, ArithmeticUtils.gcd(a, -b));
+ Assert.assertEquals(10, ArithmeticUtils.gcd(-a, -b));
+
+ Assert.assertEquals(1, ArithmeticUtils.gcd(a, c));
+ Assert.assertEquals(1, ArithmeticUtils.gcd(-a, c));
+ Assert.assertEquals(1, ArithmeticUtils.gcd(a, -c));
+ Assert.assertEquals(1, ArithmeticUtils.gcd(-a, -c));
+
+ Assert.assertEquals(3 * (1<<15), ArithmeticUtils.gcd(3 * (1<<20), 9 * (1<<15)));
+
+ Assert.assertEquals(Integer.MAX_VALUE, ArithmeticUtils.gcd(Integer.MAX_VALUE, 0));
+ Assert.assertEquals(Integer.MAX_VALUE, ArithmeticUtils.gcd(-Integer.MAX_VALUE, 0));
+ Assert.assertEquals(1<<30, ArithmeticUtils.gcd(1<<30, -Integer.MIN_VALUE));
+ try {
+ // gcd(Integer.MIN_VALUE, 0) > Integer.MAX_VALUE
+ ArithmeticUtils.gcd(Integer.MIN_VALUE, 0);
+ Assert.fail("expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+ try {
+ // gcd(0, Integer.MIN_VALUE) > Integer.MAX_VALUE
+ ArithmeticUtils.gcd(0, Integer.MIN_VALUE);
+ Assert.fail("expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+ try {
+ // gcd(Integer.MIN_VALUE, Integer.MIN_VALUE) > Integer.MAX_VALUE
+ ArithmeticUtils.gcd(Integer.MIN_VALUE, Integer.MIN_VALUE);
+ Assert.fail("expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testGcdConsistency() {
+ // Use Integer to prevent varargs vs array issue with Arrays.asList
+ Integer[] primeList = {19, 23, 53, 67, 73, 79, 101, 103, 111, 131};
+
+ for (int i = 0; i < 20; i++) {
+ Collections.shuffle(Arrays.asList(primeList));
+ int p1 = primeList[0];
+ int p2 = primeList[1];
+ int p3 = primeList[2];
+ int p4 = primeList[3];
+ int i1 = p1 * p2 * p3;
+ int i2 = p1 * p2 * p4;
+ int gcd = p1 * p2;
+ Assert.assertEquals(gcd, ArithmeticUtils.gcd(i1, i2));
+ long l1 = i1;
+ long l2 = i2;
+ Assert.assertEquals(gcd, ArithmeticUtils.gcd(l1, l2));
+ }
+ }
+
+ @Test
+ public void testGcdLong(){
+ long a = 30;
+ long b = 50;
+ long c = 77;
+
+ Assert.assertEquals(0, ArithmeticUtils.gcd(0L, 0));
+
+ Assert.assertEquals(b, ArithmeticUtils.gcd(0, b));
+ Assert.assertEquals(a, ArithmeticUtils.gcd(a, 0));
+ Assert.assertEquals(b, ArithmeticUtils.gcd(0, -b));
+ Assert.assertEquals(a, ArithmeticUtils.gcd(-a, 0));
+
+ Assert.assertEquals(10, ArithmeticUtils.gcd(a, b));
+ Assert.assertEquals(10, ArithmeticUtils.gcd(-a, b));
+ Assert.assertEquals(10, ArithmeticUtils.gcd(a, -b));
+ Assert.assertEquals(10, ArithmeticUtils.gcd(-a, -b));
+
+ Assert.assertEquals(1, ArithmeticUtils.gcd(a, c));
+ Assert.assertEquals(1, ArithmeticUtils.gcd(-a, c));
+ Assert.assertEquals(1, ArithmeticUtils.gcd(a, -c));
+ Assert.assertEquals(1, ArithmeticUtils.gcd(-a, -c));
+
+ Assert.assertEquals(3L * (1L<<45), ArithmeticUtils.gcd(3L * (1L<<50), 9L * (1L<<45)));
+
+ Assert.assertEquals(1L<<45, ArithmeticUtils.gcd(1L<<45, Long.MIN_VALUE));
+
+ Assert.assertEquals(Long.MAX_VALUE, ArithmeticUtils.gcd(Long.MAX_VALUE, 0L));
+ Assert.assertEquals(Long.MAX_VALUE, ArithmeticUtils.gcd(-Long.MAX_VALUE, 0L));
+ Assert.assertEquals(1, ArithmeticUtils.gcd(60247241209L, 153092023L));
+ try {
+ // gcd(Long.MIN_VALUE, 0) > Long.MAX_VALUE
+ ArithmeticUtils.gcd(Long.MIN_VALUE, 0);
+ Assert.fail("expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+ try {
+ // gcd(0, Long.MIN_VALUE) > Long.MAX_VALUE
+ ArithmeticUtils.gcd(0, Long.MIN_VALUE);
+ Assert.fail("expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+ try {
+ // gcd(Long.MIN_VALUE, Long.MIN_VALUE) > Long.MAX_VALUE
+ ArithmeticUtils.gcd(Long.MIN_VALUE, Long.MIN_VALUE);
+ Assert.fail("expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+ }
+
+
+ @Test
+ public void testLcm() {
+ int a = 30;
+ int b = 50;
+ int c = 77;
+
+ Assert.assertEquals(0, ArithmeticUtils.lcm(0, b));
+ Assert.assertEquals(0, ArithmeticUtils.lcm(a, 0));
+ Assert.assertEquals(b, ArithmeticUtils.lcm(1, b));
+ Assert.assertEquals(a, ArithmeticUtils.lcm(a, 1));
+ Assert.assertEquals(150, ArithmeticUtils.lcm(a, b));
+ Assert.assertEquals(150, ArithmeticUtils.lcm(-a, b));
+ Assert.assertEquals(150, ArithmeticUtils.lcm(a, -b));
+ Assert.assertEquals(150, ArithmeticUtils.lcm(-a, -b));
+ Assert.assertEquals(2310, ArithmeticUtils.lcm(a, c));
+
+ // Assert that no intermediate value overflows:
+ // The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b)
+ Assert.assertEquals((1<<20)*15, ArithmeticUtils.lcm((1<<20)*3, (1<<20)*5));
+
+ // Special case
+ Assert.assertEquals(0, ArithmeticUtils.lcm(0, 0));
+
+ try {
+ // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
+ ArithmeticUtils.lcm(Integer.MIN_VALUE, 1);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+
+ try {
+ // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
+ ArithmeticUtils.lcm(Integer.MIN_VALUE, 1<<20);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+
+ try {
+ ArithmeticUtils.lcm(Integer.MAX_VALUE, Integer.MAX_VALUE - 1);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testLcmLong() {
+ long a = 30;
+ long b = 50;
+ long c = 77;
+
+ Assert.assertEquals(0, ArithmeticUtils.lcm(0, b));
+ Assert.assertEquals(0, ArithmeticUtils.lcm(a, 0));
+ Assert.assertEquals(b, ArithmeticUtils.lcm(1, b));
+ Assert.assertEquals(a, ArithmeticUtils.lcm(a, 1));
+ Assert.assertEquals(150, ArithmeticUtils.lcm(a, b));
+ Assert.assertEquals(150, ArithmeticUtils.lcm(-a, b));
+ Assert.assertEquals(150, ArithmeticUtils.lcm(a, -b));
+ Assert.assertEquals(150, ArithmeticUtils.lcm(-a, -b));
+ Assert.assertEquals(2310, ArithmeticUtils.lcm(a, c));
+
+ Assert.assertEquals(Long.MAX_VALUE, ArithmeticUtils.lcm(60247241209L, 153092023L));
+
+ // Assert that no intermediate value overflows:
+ // The naive implementation of lcm(a,b) would be (a*b)/gcd(a,b)
+ Assert.assertEquals((1L<<50)*15, ArithmeticUtils.lcm((1L<<45)*3, (1L<<50)*5));
+
+ // Special case
+ Assert.assertEquals(0L, ArithmeticUtils.lcm(0L, 0L));
+
+ try {
+ // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
+ ArithmeticUtils.lcm(Long.MIN_VALUE, 1);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+
+ try {
+ // lcm == abs(MIN_VALUE) cannot be represented as a nonnegative int
+ ArithmeticUtils.lcm(Long.MIN_VALUE, 1<<20);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+
+ Assert.assertEquals((long) Integer.MAX_VALUE * (Integer.MAX_VALUE - 1),
+ ArithmeticUtils.lcm((long)Integer.MAX_VALUE, Integer.MAX_VALUE - 1));
+ try {
+ ArithmeticUtils.lcm(Long.MAX_VALUE, Long.MAX_VALUE - 1);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException expected) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testMulAndCheck() {
+ int big = Integer.MAX_VALUE;
+ int bigNeg = Integer.MIN_VALUE;
+ Assert.assertEquals(big, ArithmeticUtils.mulAndCheck(big, 1));
+ try {
+ ArithmeticUtils.mulAndCheck(big, 2);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ }
+ try {
+ ArithmeticUtils.mulAndCheck(bigNeg, 2);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ }
+ }
+
+ @Test
+ public void testMulAndCheckLong() {
+ long max = Long.MAX_VALUE;
+ long min = Long.MIN_VALUE;
+ Assert.assertEquals(max, ArithmeticUtils.mulAndCheck(max, 1L));
+ Assert.assertEquals(min, ArithmeticUtils.mulAndCheck(min, 1L));
+ Assert.assertEquals(0L, ArithmeticUtils.mulAndCheck(max, 0L));
+ Assert.assertEquals(0L, ArithmeticUtils.mulAndCheck(min, 0L));
+ Assert.assertEquals(max, ArithmeticUtils.mulAndCheck(1L, max));
+ Assert.assertEquals(min, ArithmeticUtils.mulAndCheck(1L, min));
+ Assert.assertEquals(0L, ArithmeticUtils.mulAndCheck(0L, max));
+ Assert.assertEquals(0L, ArithmeticUtils.mulAndCheck(0L, min));
+ Assert.assertEquals(1L, ArithmeticUtils.mulAndCheck(-1L, -1L));
+ Assert.assertEquals(min, ArithmeticUtils.mulAndCheck(min / 2, 2));
+ testMulAndCheckLongFailure(max, 2L);
+ testMulAndCheckLongFailure(2L, max);
+ testMulAndCheckLongFailure(min, 2L);
+ testMulAndCheckLongFailure(2L, min);
+ testMulAndCheckLongFailure(min, -1L);
+ testMulAndCheckLongFailure(-1L, min);
+ }
+
+ @Test
+ public void testSubAndCheck() {
+ int big = Integer.MAX_VALUE;
+ int bigNeg = Integer.MIN_VALUE;
+ Assert.assertEquals(big, ArithmeticUtils.subAndCheck(big, 0));
+ Assert.assertEquals(bigNeg + 1, ArithmeticUtils.subAndCheck(bigNeg, -1));
+ Assert.assertEquals(-1, ArithmeticUtils.subAndCheck(bigNeg, -big));
+ try {
+ ArithmeticUtils.subAndCheck(big, -1);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ }
+ try {
+ ArithmeticUtils.subAndCheck(bigNeg, 1);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ }
+ }
+
+ @Test
+ public void testSubAndCheckErrorMessage() {
+ int big = Integer.MAX_VALUE;
+ try {
+ ArithmeticUtils.subAndCheck(big, -1);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ Assert.assertTrue(ex.getMessage().length() > 1);
+ }
+ }
+
+ @Test
+ public void testSubAndCheckLong() {
+ long max = Long.MAX_VALUE;
+ long min = Long.MIN_VALUE;
+ Assert.assertEquals(max, ArithmeticUtils.subAndCheck(max, 0));
+ Assert.assertEquals(min, ArithmeticUtils.subAndCheck(min, 0));
+ Assert.assertEquals(-max, ArithmeticUtils.subAndCheck(0, max));
+ Assert.assertEquals(min + 1, ArithmeticUtils.subAndCheck(min, -1));
+ // min == -1-max
+ Assert.assertEquals(-1, ArithmeticUtils.subAndCheck(-max - 1, -max));
+ Assert.assertEquals(max, ArithmeticUtils.subAndCheck(-1, -1 - max));
+ testSubAndCheckLongFailure(0L, min);
+ testSubAndCheckLongFailure(max, -1L);
+ testSubAndCheckLongFailure(min, 1L);
+ }
+
+ @Test
+ public void testPow() {
+
+ Assert.assertEquals(1801088541, ArithmeticUtils.pow(21, 7));
+ Assert.assertEquals(1, ArithmeticUtils.pow(21, 0));
+ try {
+ ArithmeticUtils.pow(21, -7);
+ Assert.fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected behavior
+ }
+
+ Assert.assertEquals(1801088541, ArithmeticUtils.pow(21, 7));
+ Assert.assertEquals(1, ArithmeticUtils.pow(21, 0));
+ try {
+ ArithmeticUtils.pow(21, -7);
+ Assert.fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected behavior
+ }
+
+ Assert.assertEquals(1801088541l, ArithmeticUtils.pow(21l, 7));
+ Assert.assertEquals(1l, ArithmeticUtils.pow(21l, 0));
+ try {
+ ArithmeticUtils.pow(21l, -7);
+ Assert.fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected behavior
+ }
+
+ BigInteger twentyOne = BigInteger.valueOf(21l);
+ Assert.assertEquals(BigInteger.valueOf(1801088541l), ArithmeticUtils.pow(twentyOne, 7));
+ Assert.assertEquals(BigInteger.ONE, ArithmeticUtils.pow(twentyOne, 0));
+ try {
+ ArithmeticUtils.pow(twentyOne, -7);
+ Assert.fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected behavior
+ }
+
+ Assert.assertEquals(BigInteger.valueOf(1801088541l), ArithmeticUtils.pow(twentyOne, 7l));
+ Assert.assertEquals(BigInteger.ONE, ArithmeticUtils.pow(twentyOne, 0l));
+ try {
+ ArithmeticUtils.pow(twentyOne, -7l);
+ Assert.fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected behavior
+ }
+
+ Assert.assertEquals(BigInteger.valueOf(1801088541l), ArithmeticUtils.pow(twentyOne, BigInteger.valueOf(7l)));
+ Assert.assertEquals(BigInteger.ONE, ArithmeticUtils.pow(twentyOne, BigInteger.ZERO));
+ try {
+ ArithmeticUtils.pow(twentyOne, BigInteger.valueOf(-7l));
+ Assert.fail("Expecting IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected behavior
+ }
+
+ BigInteger bigOne =
+ new BigInteger("1543786922199448028351389769265814882661837148" +
+ "4763915343722775611762713982220306372888519211" +
+ "560905579993523402015636025177602059044911261");
+ Assert.assertEquals(bigOne, ArithmeticUtils.pow(twentyOne, 103));
+ Assert.assertEquals(bigOne, ArithmeticUtils.pow(twentyOne, 103l));
+ Assert.assertEquals(bigOne, ArithmeticUtils.pow(twentyOne, BigInteger.valueOf(103l)));
+
+ }
+
+ @Test(expected=NumbersArithmeticException.class)
+ public void testPowIntOverflow() {
+ ArithmeticUtils.pow(21, 8);
+ }
+
+ @Test
+ public void testPowInt() {
+ final int base = 21;
+
+ Assert.assertEquals(85766121L,
+ ArithmeticUtils.pow(base, 6));
+ Assert.assertEquals(1801088541L,
+ ArithmeticUtils.pow(base, 7));
+ }
+
+ @Test(expected=NumbersArithmeticException.class)
+ public void testPowNegativeIntOverflow() {
+ ArithmeticUtils.pow(-21, 8);
+ }
+
+ @Test
+ public void testPowNegativeInt() {
+ final int base = -21;
+
+ Assert.assertEquals(85766121,
+ ArithmeticUtils.pow(base, 6));
+ Assert.assertEquals(-1801088541,
+ ArithmeticUtils.pow(base, 7));
+ }
+
+ @Test
+ public void testPowMinusOneInt() {
+ final int base = -1;
+ for (int i = 0; i < 100; i++) {
+ final int pow = ArithmeticUtils.pow(base, i);
+ Assert.assertEquals("i: " + i, i % 2 == 0 ? 1 : -1, pow);
+ }
+ }
+
+ @Test
+ public void testPowOneInt() {
+ final int base = 1;
+ for (int i = 0; i < 100; i++) {
+ final int pow = ArithmeticUtils.pow(base, i);
+ Assert.assertEquals("i: " + i, 1, pow);
+ }
+ }
+
+ @Test(expected=NumbersArithmeticException.class)
+ public void testPowLongOverflow() {
+ ArithmeticUtils.pow(21, 15);
+ }
+
+ @Test
+ public void testPowLong() {
+ final long base = 21;
+
+ Assert.assertEquals(154472377739119461L,
+ ArithmeticUtils.pow(base, 13));
+ Assert.assertEquals(3243919932521508681L,
+ ArithmeticUtils.pow(base, 14));
+ }
+
+ @Test(expected=NumbersArithmeticException.class)
+ public void testPowNegativeLongOverflow() {
+ ArithmeticUtils.pow(-21L, 15);
+ }
+
+ @Test
+ public void testPowNegativeLong() {
+ final long base = -21;
+
+ Assert.assertEquals(-154472377739119461L,
+ ArithmeticUtils.pow(base, 13));
+ Assert.assertEquals(3243919932521508681L,
+ ArithmeticUtils.pow(base, 14));
+ }
+
+ @Test
+ public void testPowMinusOneLong() {
+ final long base = -1;
+ for (int i = 0; i < 100; i++) {
+ final long pow = ArithmeticUtils.pow(base, i);
+ Assert.assertEquals("i: " + i, i % 2 == 0 ? 1 : -1, pow);
+ }
+ }
+
+ @Test
+ public void testPowOneLong() {
+ final long base = 1;
+ for (int i = 0; i < 100; i++) {
+ final long pow = ArithmeticUtils.pow(base, i);
+ Assert.assertEquals("i: " + i, 1, pow);
+ }
+ }
+
+ @Test
+ public void testIsPowerOfTwo() {
+ final int n = 1025;
+ final boolean[] expected = new boolean[n];
+ Arrays.fill(expected, false);
+ for (int i = 1; i < expected.length; i *= 2) {
+ expected[i] = true;
+ }
+ for (int i = 0; i < expected.length; i++) {
+ final boolean actual = ArithmeticUtils.isPowerOfTwo(i);
+ Assert.assertTrue(Integer.toString(i), actual == expected[i]);
+ }
+ }
+
+ private void testAddAndCheckLongFailure(long a, long b) {
+ try {
+ ArithmeticUtils.addAndCheck(a, b);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ // success
+ }
+ }
+
+ private void testMulAndCheckLongFailure(long a, long b) {
+ try {
+ ArithmeticUtils.mulAndCheck(a, b);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ // success
+ }
+ }
+
+ private void testSubAndCheckLongFailure(long a, long b) {
+ try {
+ ArithmeticUtils.subAndCheck(a, b);
+ Assert.fail("Expecting ArithmeticException");
+ } catch (NumbersArithmeticException ex) {
+ // success
+ }
+ }
+
+ /**
+ * Testing helper method.
+ * @return an array of int numbers containing corner cases:<ul>
+ * <li>values near the beginning of int range,</li>
+ * <li>values near the end of int range,</li>
+ * <li>values near zero</li>
+ * <li>and some randomly distributed values.</li>
+ * </ul>
+ */
+ private static int[] getIntSpecialCases() {
+ int ints[] = new int[100];
+ int i = 0;
+ ints[i++] = Integer.MAX_VALUE;
+ ints[i++] = Integer.MAX_VALUE - 1;
+ ints[i++] = 100;
+ ints[i++] = 101;
+ ints[i++] = 102;
+ ints[i++] = 300;
+ ints[i++] = 567;
+ for (int j = 0; j < 20; j++) {
+ ints[i++] = j;
+ }
+ for (int j = i - 1; j >= 0; j--) {
+ ints[i++] = ints[j] > 0 ? -ints[j] : Integer.MIN_VALUE;
+ }
+ java.util.Random r = new java.util.Random(System.nanoTime());
+ for (; i < ints.length;) {
+ ints[i++] = r.nextInt();
+ }
+ return ints;
+ }
+
+ /**
+ * Testing helper method.
+ * @return an array of long numbers containing corner cases:<ul>
+ * <li>values near the beginning of long range,</li>
+ * <li>values near the end of long range,</li>
+ * <li>values near the beginning of int range,</li>
+ * <li>values near the end of int range,</li>
+ * <li>values near zero</li>
+ * <li>and some randomly distributed values.</li>
+ * </ul>
+ */
+ private static long[] getLongSpecialCases() {
+ long longs[] = new long[100];
+ int i = 0;
+ longs[i++] = Long.MAX_VALUE;
+ longs[i++] = Long.MAX_VALUE - 1L;
+ longs[i++] = (long) Integer.MAX_VALUE + 1L;
+ longs[i++] = Integer.MAX_VALUE;
+ longs[i++] = Integer.MAX_VALUE - 1;
+ longs[i++] = 100L;
+ longs[i++] = 101L;
+ longs[i++] = 102L;
+ longs[i++] = 300L;
+ longs[i++] = 567L;
+ for (int j = 0; j < 20; j++) {
+ longs[i++] = j;
+ }
+ for (int j = i - 1; j >= 0; j--) {
+ longs[i++] = longs[j] > 0L ? -longs[j] : Long.MIN_VALUE;
+ }
+ java.util.Random r = new java.util.Random(System.nanoTime());
+ for (; i < longs.length;) {
+ longs[i++] = r.nextLong();
+ }
+ return longs;
+ }
+
+ private static long toUnsignedLong(int number) {
+ return number < 0 ? 0x100000000L + (long)number : (long)number;
+ }
+
+ private static int remainderUnsignedExpected(int dividend, int divisor) {
+ return (int)remainderUnsignedExpected(toUnsignedLong(dividend), toUnsignedLong(divisor));
+ }
+
+ private static int divideUnsignedExpected(int dividend, int divisor) {
+ return (int)divideUnsignedExpected(toUnsignedLong(dividend), toUnsignedLong(divisor));
+ }
+
+ private static BigInteger toUnsignedBigInteger(long number) {
+ return number < 0L ? BigInteger.ONE.shiftLeft(64).add(BigInteger.valueOf(number)) : BigInteger.valueOf(number);
+ }
+
+ private static long remainderUnsignedExpected(long dividend, long divisor) {
+ return toUnsignedBigInteger(dividend).remainder(toUnsignedBigInteger(divisor)).longValue();
+ }
+
+ private static long divideUnsignedExpected(long dividend, long divisor) {
+ return toUnsignedBigInteger(dividend).divide(toUnsignedBigInteger(divisor)).longValue();
+ }
+
+ @Test(timeout=5000L)
+ public void testRemainderUnsignedInt() {
+ Assert.assertEquals(36, ArithmeticUtils.remainderUnsigned(-2147479015, 63));
+ Assert.assertEquals(6, ArithmeticUtils.remainderUnsigned(-2147479015, 25));
+ }
+
+ @Test(timeout=5000L)
+ public void testRemainderUnsignedIntSpecialCases() {
+ int ints[] = getIntSpecialCases();
+ for (int dividend : ints) {
+ for (int divisor : ints) {
+ if (divisor == 0) {
+ try {
+ ArithmeticUtils.remainderUnsigned(dividend, divisor);
+ Assert.fail("Should have failed with ArithmeticException: division by zero");
+ } catch (ArithmeticException e) {
+ // Success.
+ }
+ } else {
+ Assert.assertEquals(remainderUnsignedExpected(dividend, divisor), ArithmeticUtils.remainderUnsigned(dividend, divisor));
+ }
+ }
+ }
+ }
+
+ @Test(timeout=5000L)
+ public void testRemainderUnsignedLong() {
+ Assert.assertEquals(48L, ArithmeticUtils.remainderUnsigned(-2147479015L, 63L));
+ }
+
+ @Test//(timeout=5000L)
+ public void testRemainderUnsignedLongSpecialCases() {
+ long longs[] = getLongSpecialCases();
+ for (long dividend : longs) {
+ for (long divisor : longs) {
+ if (divisor == 0L) {
+ try {
+ ArithmeticUtils.remainderUnsigned(dividend, divisor);
+ Assert.fail("Should have failed with ArithmeticException: division by zero");
+ } catch (ArithmeticException e) {
+ // Success.
+ }
+ } else {
+ Assert.assertEquals(remainderUnsignedExpected(dividend, divisor), ArithmeticUtils.remainderUnsigned(dividend, divisor));
+ }
+ }
+ }
+ }
+
+ @Test(timeout=5000L)
+ public void testDivideUnsignedInt() {
+ Assert.assertEquals(34087115, ArithmeticUtils.divideUnsigned(-2147479015, 63));
+ Assert.assertEquals(85899531, ArithmeticUtils.divideUnsigned(-2147479015, 25));
+ Assert.assertEquals(2147483646, ArithmeticUtils.divideUnsigned(-3, 2));
+ Assert.assertEquals(330382098, ArithmeticUtils.divideUnsigned(-16, 13));
+ Assert.assertEquals(306783377, ArithmeticUtils.divideUnsigned(-16, 14));
+ Assert.assertEquals(2, ArithmeticUtils.divideUnsigned(-1, 2147483647));
+ Assert.assertEquals(2, ArithmeticUtils.divideUnsigned(-2, 2147483647));
+ Assert.assertEquals(1, ArithmeticUtils.divideUnsigned(-3, 2147483647));
+ Assert.assertEquals(1, ArithmeticUtils.divideUnsigned(-16, 2147483647));
+ Assert.assertEquals(1, ArithmeticUtils.divideUnsigned(-16, 2147483646));
+ }
+
+ @Test(timeout=5000L)
+ public void testDivideUnsignedIntSpecialCases() {
+ int ints[] = getIntSpecialCases();
+ for (int dividend : ints) {
+ for (int divisor : ints) {
+ if (divisor == 0) {
+ try {
+ ArithmeticUtils.divideUnsigned(dividend, divisor);
+ Assert.fail("Should have failed with ArithmeticException: division by zero");
+ } catch (ArithmeticException e) {
+ // Success.
+ }
+ } else {
+ Assert.assertEquals(divideUnsignedExpected(dividend, divisor), ArithmeticUtils.divideUnsigned(dividend, divisor));
+ }
+ }
+ }
+ }
+
+ @Test(timeout=5000L)
+ public void testDivideUnsignedLong() {
+ Assert.assertEquals(292805461453366231L, ArithmeticUtils.divideUnsigned(-2147479015L, 63L));
+ }
+
+ @Test(timeout=5000L)
+ public void testDivideUnsignedLongSpecialCases() {
+ long longs[] = getLongSpecialCases();
+ for (long dividend : longs) {
+ for (long divisor : longs) {
+ if (divisor == 0L) {
+ try {
+ ArithmeticUtils.divideUnsigned(dividend, divisor);
+ Assert.fail("Should have failed with ArithmeticException: division by zero");
+ } catch (ArithmeticException e) {
+ // Success.
+ }
+ } else {
+ Assert.assertEquals(divideUnsignedExpected(dividend, divisor), ArithmeticUtils.divideUnsigned(dividend, divisor));
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/aaef6f7a/commons-numbers-fraction/LICENSE.txt
----------------------------------------------------------------------
diff --git a/commons-numbers-fraction/LICENSE.txt b/commons-numbers-fraction/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/commons-numbers-fraction/LICENSE.txt
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/aaef6f7a/commons-numbers-fraction/NOTICE.txt
----------------------------------------------------------------------
diff --git a/commons-numbers-fraction/NOTICE.txt b/commons-numbers-fraction/NOTICE.txt
new file mode 100644
index 0000000..ea6ae07
--- /dev/null
+++ b/commons-numbers-fraction/NOTICE.txt
@@ -0,0 +1,6 @@
+Apache Commons Numbers
+Copyright 2001-2016 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/aaef6f7a/commons-numbers-fraction/README.md
----------------------------------------------------------------------
diff --git a/commons-numbers-fraction/README.md b/commons-numbers-fraction/README.md
new file mode 100644
index 0000000..0701bed
--- /dev/null
+++ b/commons-numbers-fraction/README.md
@@ -0,0 +1,98 @@
+<!---
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!---
+ +======================================================================+
+ |**** ****|
+ |**** THIS FILE IS GENERATED BY THE COMMONS BUILD PLUGIN ****|
+ |**** DO NOT EDIT DIRECTLY ****|
+ |**** ****|
+ +======================================================================+
+ | TEMPLATE FILE: readme-md-template.md |
+ | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+ +======================================================================+
+ | |
+ | 1) Re-generate using: mvn commons:readme-md |
+ | |
+ | 2) Set the following properties in the component's pom: |
+ | - commons.componentid (required, alphabetic, lower case) |
+ | - commons.release.version (required) |
+ | |
+ | 3) Example Properties |
+ | |
+ | <properties> |
+ | <commons.componentid>math</commons.componentid> |
+ | <commons.release.version>1.2</commons.release.version> |
+ | </properties> |
+ | |
+ +======================================================================+
+--->
+Apache Commons Numbers Core
+===================
+
+Basic utilities.
+
+Documentation
+-------------
+
+More information can be found on the [homepage](https://commons.apache.org/proper/commons-numbers).
+The [JavaDoc](https://commons.apache.org/proper/commons-numbers/javadocs/api-release) can be browsed.
+Questions related to the usage of Apache Commons Numbers Core should be posted to the [user mailing list][ml].
+
+Where can I get the latest release?
+-----------------------------------
+You can download source and binaries from our [download page](https://commons.apache.org/proper/commons-numbers/download_numbers.cgi).
+
+Alternatively you can pull it from the central Maven repositories:
+
+```xml
+<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-numbers-core</artifactId>
+ <version>1.0</version>
+</dependency>
+```
+
+Contributing
+------------
+
+We accept PRs via github. The [developer mailing list][ml] is the main channel of communication for contributors.
+There are some guidelines which will make applying PRs easier for us:
++ No tabs! Please use spaces for indentation.
++ Respect the code style.
++ Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted create a separate PR for this change.
++ Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running ```mvn clean test```.
+
+If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas).
+You can learn more about contributing via GitHub in our [contribution guidelines](CONTRIBUTING.md).
+
+License
+-------
+Code is under the [Apache Licence v2](https://www.apache.org/licenses/LICENSE-2.0.txt).
+
+Donations
+---------
+You like Apache Commons Numbers Core? Then [donate back to the ASF](https://www.apache.org/foundation/contributing.html) to support the development.
+
+Additional Resources
+--------------------
+
++ [Apache Commons Homepage](https://commons.apache.org/)
++ [Apache Bugtracker (JIRA)](https://issues.apache.org/jira/)
++ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons)
++ #apachecommons IRC channel on freenode.org
+
+[ml]:https://commons.apache.org/mail-lists.html
http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/aaef6f7a/commons-numbers-fraction/pom.xml
----------------------------------------------------------------------
diff --git a/commons-numbers-fraction/pom.xml b/commons-numbers-fraction/pom.xml
new file mode 100644
index 0000000..42c3aa5
--- /dev/null
+++ b/commons-numbers-fraction/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-numbers-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-numbers-fraction</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <name>Apache Commons Numbers Fraction</name>
+
+ <description>Fraction utilities.</description>
+
+ <properties>
+ <!-- This value must reflect the current name of the base package. -->
+ <commons.osgi.symbolicName>org.apache.commons.numbers.</commons.osgi.symbolicName>
+ <!-- OSGi -->
+ <commons.osgi.export>org.apache.commons.numbers.fraction</commons.osgi.export>
+ <!-- Workaround to avoid duplicating config files. -->
+ <numbers.parent.dir>${basedir}/..</numbers.parent.dir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-numbers-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-numbers-core</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>