You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2019/06/30 21:55:55 UTC
[commons-numbers] 08/09: NUMBERS-124: Constructor was actually a
conversion method.
This is an automated email from the ASF dual-hosted git repository.
erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit efc9ec3705ece9a295744dfd2be927b211768d67
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Sun Jun 30 23:45:07 2019 +0200
NUMBERS-124: Constructor was actually a conversion method.
---
.../commons/numbers/fraction/BigFraction.java | 128 ++++++++++-----------
1 file changed, 62 insertions(+), 66 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index 6ef2549..6d33b62 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -49,10 +49,10 @@ public class BigFraction extends Number implements Comparable<BigFraction>, Seri
private final BigInteger denominator;
/**
- * Private constructor for BigFraction ofInt() factory methods.
+ * Private constructor: Instances are created using factory methods.
*
- * @param num the numerator, must not be {@code null}.
- * @param den the denominator, must not be {@code null}.
+ * @param num Numerator, must not be {@code null}.
+ * @param den Denominator, must not be {@code null}.
* @throws ArithmeticException if the denominator is zero.
*/
private BigFraction(BigInteger num, BigInteger den) {
@@ -86,41 +86,39 @@ public class BigFraction extends Number implements Comparable<BigFraction>, Seri
}
/**
- * Create a fraction given the double value and either the maximum error
- * allowed or the maximum number of denominator digits.
- * <p>
+ * Create a fraction given the double value and either the maximum
+ * error allowed or the maximum number of denominator digits.
*
- * NOTE: This constructor is called with EITHER - a valid epsilon value and
- * the maxDenominator set to Integer.MAX_VALUE (that way the maxDenominator
- * has no effect). OR - a valid maxDenominator value and the epsilon value
- * set to zero (that way epsilon only has effect if there is an exact match
- * before the maxDenominator value is reached).
+ * <p>
+ * NOTE: This method is called with
+ * - EITHER a valid epsilon value and the maxDenominator set to
+ * Integer.MAX_VALUE (that way the maxDenominator has no effect)
+ * - OR a valid maxDenominator value and the epsilon value set to
+ * zero (that way epsilon only has effect if there is an exact
+ * match before the maxDenominator value is reached).
* </p>
* <p>
- *
- * It has been done this way so that the same code can be (re)used for both
- * scenarios. However this could be confusing to users if it were part of
- * the public API and this constructor should therefore remain PRIVATE.
+ * It has been done this way so that the same code can be reused for
+ * both scenarios. However this could be confusing to users if it
+ * were part of the public API and this method should therefore remain
+ * PRIVATE.
* </p>
*
* See JIRA issue ticket MATH-181 for more details:
+ * https://issues.apache.org/jira/browse/MATH-181
*
- * https://issues.apache.org/jira/browse/MATH-181
- *
- * @param value
- * the double value to convert to a fraction.
- * @param epsilon
- * maximum error allowed. The resulting fraction is within
- * <code>epsilon</code> of <code>value</code>, in absolute terms.
- * @param maxDenominator
- * maximum denominator value allowed.
- * @param maxIterations
- * maximum number of convergents.
- * @throws ArithmeticException
- * if the continued fraction failed to converge.
+ * @param value Value to convert to a fraction.
+ * @param epsilon Maximum error allowed.
+ * The resulting fraction is within {@code epsilon} of {@code value},
+ * in absolute terms.
+ * @param maxDenominator Maximum denominator value allowed.
+ * @param maxIterations Maximum number of convergents.
+ * @throws ArithmeticException if the continued fraction failed to converge.
*/
- private BigFraction(final double value, final double epsilon,
- final int maxDenominator, int maxIterations) {
+ private static BigFraction from(final double value,
+ final double epsilon,
+ final int maxDenominator,
+ final int maxIterations) {
long overflow = Integer.MAX_VALUE;
double r0 = value;
long a0 = (long) Math.floor(r0);
@@ -132,9 +130,8 @@ public class BigFraction extends Number implements Comparable<BigFraction>, Seri
// check for (almost) integer arguments, which should not go
// to iterations.
if (Math.abs(a0 - value) < epsilon) {
- numerator = BigInteger.valueOf(a0);
- denominator = BigInteger.ONE;
- return;
+ return new BigFraction(BigInteger.valueOf(a0),
+ BigInteger.ONE);
}
long p0 = 1;
@@ -149,23 +146,25 @@ public class BigFraction extends Number implements Comparable<BigFraction>, Seri
boolean stop = false;
do {
++n;
- final double r1 = 1.0 / (r0 - a0);
+ final double r1 = 1d / (r0 - a0);
final long a1 = (long) Math.floor(r1);
p2 = (a1 * p1) + p0;
q2 = (a1 * q1) + q0;
- if ((p2 > overflow) || (q2 > overflow)) {
+ if (p2 > overflow ||
+ q2 > overflow) {
// in maxDenominator mode, if the last fraction was very close to the actual value
// q2 may overflow in the next iteration; in this case return the last one.
- if (epsilon == 0.0 && Math.abs(q1) < maxDenominator) {
+ if (epsilon == 0 &&
+ Math.abs(q1) < maxDenominator) {
break;
}
throw new FractionException(FractionException.ERROR_CONVERSION_OVERFLOW, value, p2, q2);
}
final double convergent = (double) p2 / (double) q2;
- if ((n < maxIterations) &&
- (Math.abs(convergent - value) > epsilon) &&
- (q2 < maxDenominator)) {
+ if (n < maxIterations &&
+ Math.abs(convergent - value) > epsilon &&
+ q2 < maxDenominator) {
p0 = p1;
p1 = p2;
q0 = q1;
@@ -180,13 +179,12 @@ public class BigFraction extends Number implements Comparable<BigFraction>, Seri
if (n >= maxIterations) {
throw new FractionException(FractionException.ERROR_CONVERSION, value, maxIterations);
}
- if (q2 < maxDenominator) {
- numerator = BigInteger.valueOf(p2);
- denominator = BigInteger.valueOf(q2);
- } else {
- numerator = BigInteger.valueOf(p1);
- denominator = BigInteger.valueOf(q1);
- }
+
+ return q2 < maxDenominator ?
+ new BigFraction(BigInteger.valueOf(p2),
+ BigInteger.valueOf(q2)) :
+ new BigFraction(BigInteger.valueOf(p1),
+ BigInteger.valueOf(q1));
}
/**
@@ -233,10 +231,11 @@ public class BigFraction extends Number implements Comparable<BigFraction>, Seri
* (this number cannot be stored exactly in IEEE754).
* </p>
*
- * @see BigFraction#from(double, double, int)
* @param value Value to convert to a fraction.
* @throws IllegalArgumentException if the given {@code value} is NaN or infinite.
* @return a new instance.
+ *
+ * @see #from(double,double,int)
*/
public static BigFraction from(final double value) {
if (Double.isNaN(value)) {
@@ -292,22 +291,19 @@ public class BigFraction extends Number implements Comparable<BigFraction>, Seri
* Continued Fraction</a> equations (11) and (22)-(26)</li>
* </ul>
*
- * @param value
- * the double value to convert to a fraction.
- * @param epsilon
- * maximum error allowed. The resulting fraction is within
- * <code>epsilon</code> of <code>value</code>, in absolute terms.
- * @param maxIterations
- * maximum number of convergents.
- * @throws ArithmeticException
- * if the continued fraction failed to converge.
- * @see #BigFraction(double)
+ * @param value Value to convert to a fraction.
+ * @param epsilon Maximum error allowed. The resulting fraction is within
+ * <code>epsilon</code> of <code>value</code>, in absolute terms.
+ * @param maxIterations Maximum number of convergents.
+ * @throws ArithmeticException if the continued fraction failed to converge.
* @return a new instance.
+ *
+ * @see #from(double,int)
*/
public static BigFraction from(final double value,
final double epsilon,
final int maxIterations) {
- return new BigFraction(value, epsilon, Integer.MAX_VALUE, maxIterations);
+ return from(value, epsilon, Integer.MAX_VALUE, maxIterations);
}
/**
@@ -319,16 +315,16 @@ public class BigFraction extends Number implements Comparable<BigFraction>, Seri
* Continued Fraction</a> equations (11) and (22)-(26)</li>
* </ul>
*
- * @param value
- * the double value to convert to a fraction.
- * @param maxDenominator
- * The maximum allowed value for denominator.
- * @throws ArithmeticException
- * if the continued fraction failed to converge.
+ * @param value Value to convert to a fraction.
+ * @param maxDenominator Maximum allowed value for denominator.
+ * @throws ArithmeticException if the continued fraction failed to converge.
* @return a new instance.
+ *
+ * @see #from(double,double,int)
*/
- public static BigFraction from(final double value, final int maxDenominator) {
- return new BigFraction(value, 0, maxDenominator, 100);
+ public static BigFraction from(final double value,
+ final int maxDenominator) {
+ return from(value, 0, maxDenominator, 100);
}
/**