001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math3.fraction;
018
019 import java.io.Serializable;
020 import java.math.BigDecimal;
021 import java.math.BigInteger;
022
023 import org.apache.commons.math3.FieldElement;
024 import org.apache.commons.math3.exception.MathArithmeticException;
025 import org.apache.commons.math3.exception.MathIllegalArgumentException;
026 import org.apache.commons.math3.exception.NullArgumentException;
027 import org.apache.commons.math3.exception.ZeroException;
028 import org.apache.commons.math3.exception.util.LocalizedFormats;
029 import org.apache.commons.math3.util.ArithmeticUtils;
030 import org.apache.commons.math3.util.FastMath;
031 import org.apache.commons.math3.util.MathUtils;
032
033 /**
034 * Representation of a rational number without any overflow. This class is
035 * immutable.
036 *
037 * @version $Id: BigFraction.java 1416643 2012-12-03 19:37:14Z tn $
038 * @since 2.0
039 */
040 public class BigFraction
041 extends Number
042 implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable {
043
044 /** A fraction representing "2 / 1". */
045 public static final BigFraction TWO = new BigFraction(2);
046
047 /** A fraction representing "1". */
048 public static final BigFraction ONE = new BigFraction(1);
049
050 /** A fraction representing "0". */
051 public static final BigFraction ZERO = new BigFraction(0);
052
053 /** A fraction representing "-1 / 1". */
054 public static final BigFraction MINUS_ONE = new BigFraction(-1);
055
056 /** A fraction representing "4/5". */
057 public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5);
058
059 /** A fraction representing "1/5". */
060 public static final BigFraction ONE_FIFTH = new BigFraction(1, 5);
061
062 /** A fraction representing "1/2". */
063 public static final BigFraction ONE_HALF = new BigFraction(1, 2);
064
065 /** A fraction representing "1/4". */
066 public static final BigFraction ONE_QUARTER = new BigFraction(1, 4);
067
068 /** A fraction representing "1/3". */
069 public static final BigFraction ONE_THIRD = new BigFraction(1, 3);
070
071 /** A fraction representing "3/5". */
072 public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5);
073
074 /** A fraction representing "3/4". */
075 public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4);
076
077 /** A fraction representing "2/5". */
078 public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5);
079
080 /** A fraction representing "2/4". */
081 public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4);
082
083 /** A fraction representing "2/3". */
084 public static final BigFraction TWO_THIRDS = new BigFraction(2, 3);
085
086 /** Serializable version identifier. */
087 private static final long serialVersionUID = -5630213147331578515L;
088
089 /** <code>BigInteger</code> representation of 100. */
090 private static final BigInteger ONE_HUNDRED = BigInteger.valueOf(100);
091
092 /** The numerator. */
093 private final BigInteger numerator;
094
095 /** The denominator. */
096 private final BigInteger denominator;
097
098 /**
099 * <p>
100 * Create a {@link BigFraction} equivalent to the passed <tt>BigInteger</tt>, ie
101 * "num / 1".
102 * </p>
103 *
104 * @param num
105 * the numerator.
106 */
107 public BigFraction(final BigInteger num) {
108 this(num, BigInteger.ONE);
109 }
110
111 /**
112 * Create a {@link BigFraction} given the numerator and denominator as
113 * {@code BigInteger}. The {@link BigFraction} is reduced to lowest terms.
114 *
115 * @param num the numerator, must not be {@code null}.
116 * @param den the denominator, must not be {@code null}.
117 * @throws ZeroException if the denominator is zero.
118 * @throws NullArgumentException if either of the arguments is null
119 */
120 public BigFraction(BigInteger num, BigInteger den) {
121 MathUtils.checkNotNull(num, LocalizedFormats.NUMERATOR);
122 MathUtils.checkNotNull(den, LocalizedFormats.DENOMINATOR);
123 if (BigInteger.ZERO.equals(den)) {
124 throw new ZeroException(LocalizedFormats.ZERO_DENOMINATOR);
125 }
126 if (BigInteger.ZERO.equals(num)) {
127 numerator = BigInteger.ZERO;
128 denominator = BigInteger.ONE;
129 } else {
130
131 // reduce numerator and denominator by greatest common denominator
132 final BigInteger gcd = num.gcd(den);
133 if (BigInteger.ONE.compareTo(gcd) < 0) {
134 num = num.divide(gcd);
135 den = den.divide(gcd);
136 }
137
138 // move sign to numerator
139 if (BigInteger.ZERO.compareTo(den) > 0) {
140 num = num.negate();
141 den = den.negate();
142 }
143
144 // store the values in the final fields
145 numerator = num;
146 denominator = den;
147
148 }
149 }
150
151 /**
152 * Create a fraction given the double value.
153 * <p>
154 * This constructor behaves <em>differently</em> from
155 * {@link #BigFraction(double, double, int)}. It converts the double value
156 * exactly, considering its internal bits representation. This works for all
157 * values except NaN and infinities and does not requires any loop or
158 * convergence threshold.
159 * </p>
160 * <p>
161 * Since this conversion is exact and since double numbers are sometimes
162 * approximated, the fraction created may seem strange in some cases. For example,
163 * calling <code>new BigFraction(1.0 / 3.0)</code> does <em>not</em> create
164 * the fraction 1/3, but the fraction 6004799503160661 / 18014398509481984
165 * because the double number passed to the constructor is not exactly 1/3
166 * (this number cannot be stored exactly in IEEE754).
167 * </p>
168 * @see #BigFraction(double, double, int)
169 * @param value the double value to convert to a fraction.
170 * @exception MathIllegalArgumentException if value is NaN or infinite
171 */
172 public BigFraction(final double value) throws MathIllegalArgumentException {
173 if (Double.isNaN(value)) {
174 throw new MathIllegalArgumentException(LocalizedFormats.NAN_VALUE_CONVERSION);
175 }
176 if (Double.isInfinite(value)) {
177 throw new MathIllegalArgumentException(LocalizedFormats.INFINITE_VALUE_CONVERSION);
178 }
179
180 // compute m and k such that value = m * 2^k
181 final long bits = Double.doubleToLongBits(value);
182 final long sign = bits & 0x8000000000000000L;
183 final long exponent = bits & 0x7ff0000000000000L;
184 long m = bits & 0x000fffffffffffffL;
185 if (exponent != 0) {
186 // this was a normalized number, add the implicit most significant bit
187 m |= 0x0010000000000000L;
188 }
189 if (sign != 0) {
190 m = -m;
191 }
192 int k = ((int) (exponent >> 52)) - 1075;
193 while (((m & 0x001ffffffffffffeL) != 0) && ((m & 0x1) == 0)) {
194 m = m >> 1;
195 ++k;
196 }
197
198 if (k < 0) {
199 numerator = BigInteger.valueOf(m);
200 denominator = BigInteger.ZERO.flipBit(-k);
201 } else {
202 numerator = BigInteger.valueOf(m).multiply(BigInteger.ZERO.flipBit(k));
203 denominator = BigInteger.ONE;
204 }
205
206 }
207
208 /**
209 * Create a fraction given the double value and maximum error allowed.
210 * <p>
211 * References:
212 * <ul>
213 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
214 * Continued Fraction</a> equations (11) and (22)-(26)</li>
215 * </ul>
216 * </p>
217 *
218 * @param value
219 * the double value to convert to a fraction.
220 * @param epsilon
221 * maximum error allowed. The resulting fraction is within
222 * <code>epsilon</code> of <code>value</code>, in absolute terms.
223 * @param maxIterations
224 * maximum number of convergents.
225 * @throws FractionConversionException
226 * if the continued fraction failed to converge.
227 * @see #BigFraction(double)
228 */
229 public BigFraction(final double value, final double epsilon,
230 final int maxIterations)
231 throws FractionConversionException {
232 this(value, epsilon, Integer.MAX_VALUE, maxIterations);
233 }
234
235 /**
236 * Create a fraction given the double value and either the maximum error
237 * allowed or the maximum number of denominator digits.
238 * <p>
239 *
240 * NOTE: This constructor is called with EITHER - a valid epsilon value and
241 * the maxDenominator set to Integer.MAX_VALUE (that way the maxDenominator
242 * has no effect). OR - a valid maxDenominator value and the epsilon value
243 * set to zero (that way epsilon only has effect if there is an exact match
244 * before the maxDenominator value is reached).
245 * </p>
246 * <p>
247 *
248 * It has been done this way so that the same code can be (re)used for both
249 * scenarios. However this could be confusing to users if it were part of
250 * the public API and this constructor should therefore remain PRIVATE.
251 * </p>
252 *
253 * See JIRA issue ticket MATH-181 for more details:
254 *
255 * https://issues.apache.org/jira/browse/MATH-181
256 *
257 * @param value
258 * the double value to convert to a fraction.
259 * @param epsilon
260 * maximum error allowed. The resulting fraction is within
261 * <code>epsilon</code> of <code>value</code>, in absolute terms.
262 * @param maxDenominator
263 * maximum denominator value allowed.
264 * @param maxIterations
265 * maximum number of convergents.
266 * @throws FractionConversionException
267 * if the continued fraction failed to converge.
268 */
269 private BigFraction(final double value, final double epsilon,
270 final int maxDenominator, int maxIterations)
271 throws FractionConversionException {
272 long overflow = Integer.MAX_VALUE;
273 double r0 = value;
274 long a0 = (long) FastMath.floor(r0);
275 if (a0 > overflow) {
276 throw new FractionConversionException(value, a0, 1l);
277 }
278
279 // check for (almost) integer arguments, which should not go
280 // to iterations.
281 if (FastMath.abs(a0 - value) < epsilon) {
282 numerator = BigInteger.valueOf(a0);
283 denominator = BigInteger.ONE;
284 return;
285 }
286
287 long p0 = 1;
288 long q0 = 0;
289 long p1 = a0;
290 long q1 = 1;
291
292 long p2 = 0;
293 long q2 = 1;
294
295 int n = 0;
296 boolean stop = false;
297 do {
298 ++n;
299 final double r1 = 1.0 / (r0 - a0);
300 final long a1 = (long) FastMath.floor(r1);
301 p2 = (a1 * p1) + p0;
302 q2 = (a1 * q1) + q0;
303 if ((p2 > overflow) || (q2 > overflow)) {
304 throw new FractionConversionException(value, p2, q2);
305 }
306
307 final double convergent = (double) p2 / (double) q2;
308 if ((n < maxIterations) &&
309 (FastMath.abs(convergent - value) > epsilon) &&
310 (q2 < maxDenominator)) {
311 p0 = p1;
312 p1 = p2;
313 q0 = q1;
314 q1 = q2;
315 a0 = a1;
316 r0 = r1;
317 } else {
318 stop = true;
319 }
320 } while (!stop);
321
322 if (n >= maxIterations) {
323 throw new FractionConversionException(value, maxIterations);
324 }
325
326 if (q2 < maxDenominator) {
327 numerator = BigInteger.valueOf(p2);
328 denominator = BigInteger.valueOf(q2);
329 } else {
330 numerator = BigInteger.valueOf(p1);
331 denominator = BigInteger.valueOf(q1);
332 }
333 }
334
335 /**
336 * Create a fraction given the double value and maximum denominator.
337 * <p>
338 * References:
339 * <ul>
340 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
341 * Continued Fraction</a> equations (11) and (22)-(26)</li>
342 * </ul>
343 * </p>
344 *
345 * @param value
346 * the double value to convert to a fraction.
347 * @param maxDenominator
348 * The maximum allowed value for denominator.
349 * @throws FractionConversionException
350 * if the continued fraction failed to converge.
351 */
352 public BigFraction(final double value, final int maxDenominator)
353 throws FractionConversionException {
354 this(value, 0, maxDenominator, 100);
355 }
356
357 /**
358 * <p>
359 * Create a {@link BigFraction} equivalent to the passed <tt>int</tt>, ie
360 * "num / 1".
361 * </p>
362 *
363 * @param num
364 * the numerator.
365 */
366 public BigFraction(final int num) {
367 this(BigInteger.valueOf(num), BigInteger.ONE);
368 }
369
370 /**
371 * <p>
372 * Create a {@link BigFraction} given the numerator and denominator as simple
373 * <tt>int</tt>. The {@link BigFraction} is reduced to lowest terms.
374 * </p>
375 *
376 * @param num
377 * the numerator.
378 * @param den
379 * the denominator.
380 */
381 public BigFraction(final int num, final int den) {
382 this(BigInteger.valueOf(num), BigInteger.valueOf(den));
383 }
384
385 /**
386 * <p>
387 * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1".
388 * </p>
389 *
390 * @param num
391 * the numerator.
392 */
393 public BigFraction(final long num) {
394 this(BigInteger.valueOf(num), BigInteger.ONE);
395 }
396
397 /**
398 * <p>
399 * Create a {@link BigFraction} given the numerator and denominator as simple
400 * <tt>long</tt>. The {@link BigFraction} is reduced to lowest terms.
401 * </p>
402 *
403 * @param num
404 * the numerator.
405 * @param den
406 * the denominator.
407 */
408 public BigFraction(final long num, final long den) {
409 this(BigInteger.valueOf(num), BigInteger.valueOf(den));
410 }
411
412 /**
413 * <p>
414 * Creates a <code>BigFraction</code> instance with the 2 parts of a fraction
415 * Y/Z.
416 * </p>
417 *
418 * <p>
419 * Any negative signs are resolved to be on the numerator.
420 * </p>
421 *
422 * @param numerator
423 * the numerator, for example the three in 'three sevenths'.
424 * @param denominator
425 * the denominator, for example the seven in 'three sevenths'.
426 * @return a new fraction instance, with the numerator and denominator
427 * reduced.
428 * @throws ArithmeticException
429 * if the denominator is <code>zero</code>.
430 */
431 public static BigFraction getReducedFraction(final int numerator,
432 final int denominator) {
433 if (numerator == 0) {
434 return ZERO; // normalize zero.
435 }
436
437 return new BigFraction(numerator, denominator);
438 }
439
440 /**
441 * <p>
442 * Returns the absolute value of this {@link BigFraction}.
443 * </p>
444 *
445 * @return the absolute value as a {@link BigFraction}.
446 */
447 public BigFraction abs() {
448 return (BigInteger.ZERO.compareTo(numerator) <= 0) ? this : negate();
449 }
450
451 /**
452 * <p>
453 * Adds the value of this fraction to the passed {@link BigInteger},
454 * returning the result in reduced form.
455 * </p>
456 *
457 * @param bg
458 * the {@link BigInteger} to add, must'nt be <code>null</code>.
459 * @return a <code>BigFraction</code> instance with the resulting values.
460 * @throws NullArgumentException
461 * if the {@link BigInteger} is <code>null</code>.
462 */
463 public BigFraction add(final BigInteger bg) throws NullArgumentException {
464 MathUtils.checkNotNull(bg);
465 return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
466 }
467
468 /**
469 * <p>
470 * Adds the value of this fraction to the passed <tt>integer</tt>, returning
471 * the result in reduced form.
472 * </p>
473 *
474 * @param i
475 * the <tt>integer</tt> to add.
476 * @return a <code>BigFraction</code> instance with the resulting values.
477 */
478 public BigFraction add(final int i) {
479 return add(BigInteger.valueOf(i));
480 }
481
482 /**
483 * <p>
484 * Adds the value of this fraction to the passed <tt>long</tt>, returning
485 * the result in reduced form.
486 * </p>
487 *
488 * @param l
489 * the <tt>long</tt> to add.
490 * @return a <code>BigFraction</code> instance with the resulting values.
491 */
492 public BigFraction add(final long l) {
493 return add(BigInteger.valueOf(l));
494 }
495
496 /**
497 * <p>
498 * Adds the value of this fraction to another, returning the result in
499 * reduced form.
500 * </p>
501 *
502 * @param fraction
503 * the {@link BigFraction} to add, must not be <code>null</code>.
504 * @return a {@link BigFraction} instance with the resulting values.
505 * @throws NullArgumentException if the {@link BigFraction} is {@code null}.
506 */
507 public BigFraction add(final BigFraction fraction) {
508 if (fraction == null) {
509 throw new NullArgumentException(LocalizedFormats.FRACTION);
510 }
511 if (ZERO.equals(fraction)) {
512 return this;
513 }
514
515 BigInteger num = null;
516 BigInteger den = null;
517
518 if (denominator.equals(fraction.denominator)) {
519 num = numerator.add(fraction.numerator);
520 den = denominator;
521 } else {
522 num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
523 den = denominator.multiply(fraction.denominator);
524 }
525 return new BigFraction(num, den);
526
527 }
528
529 /**
530 * <p>
531 * Gets the fraction as a <code>BigDecimal</code>. This calculates the
532 * fraction as the numerator divided by denominator.
533 * </p>
534 *
535 * @return the fraction as a <code>BigDecimal</code>.
536 * @throws ArithmeticException
537 * if the exact quotient does not have a terminating decimal
538 * expansion.
539 * @see BigDecimal
540 */
541 public BigDecimal bigDecimalValue() {
542 return new BigDecimal(numerator).divide(new BigDecimal(denominator));
543 }
544
545 /**
546 * <p>
547 * Gets the fraction as a <code>BigDecimal</code> following the passed
548 * rounding mode. This calculates the fraction as the numerator divided by
549 * denominator.
550 * </p>
551 *
552 * @param roundingMode
553 * rounding mode to apply. see {@link BigDecimal} constants.
554 * @return the fraction as a <code>BigDecimal</code>.
555 * @throws IllegalArgumentException
556 * if <tt>roundingMode</tt> does not represent a valid rounding
557 * mode.
558 * @see BigDecimal
559 */
560 public BigDecimal bigDecimalValue(final int roundingMode) {
561 return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode);
562 }
563
564 /**
565 * <p>
566 * Gets the fraction as a <code>BigDecimal</code> following the passed scale
567 * and rounding mode. This calculates the fraction as the numerator divided
568 * by denominator.
569 * </p>
570 *
571 * @param scale
572 * scale of the <code>BigDecimal</code> quotient to be returned.
573 * see {@link BigDecimal} for more information.
574 * @param roundingMode
575 * rounding mode to apply. see {@link BigDecimal} constants.
576 * @return the fraction as a <code>BigDecimal</code>.
577 * @see BigDecimal
578 */
579 public BigDecimal bigDecimalValue(final int scale, final int roundingMode) {
580 return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);
581 }
582
583 /**
584 * <p>
585 * Compares this object to another based on size.
586 * </p>
587 *
588 * @param object
589 * the object to compare to, must not be <code>null</code>.
590 * @return -1 if this is less than <tt>object</tt>, +1 if this is greater
591 * than <tt>object</tt>, 0 if they are equal.
592 * @see java.lang.Comparable#compareTo(java.lang.Object)
593 */
594 public int compareTo(final BigFraction object) {
595 BigInteger nOd = numerator.multiply(object.denominator);
596 BigInteger dOn = denominator.multiply(object.numerator);
597 return nOd.compareTo(dOn);
598 }
599
600 /**
601 * <p>
602 * Divide the value of this fraction by the passed {@code BigInteger},
603 * ie {@code this * 1 / bg}, returning the result in reduced form.
604 * </p>
605 *
606 * @param bg the {@code BigInteger} to divide by, must not be {@code null}
607 * @return a {@link BigFraction} instance with the resulting values
608 * @throws NullArgumentException if the {@code BigInteger} is {@code null}
609 * @throws MathArithmeticException if the fraction to divide by is zero
610 */
611 public BigFraction divide(final BigInteger bg) {
612 if (bg == null) {
613 throw new NullArgumentException(LocalizedFormats.FRACTION);
614 }
615 if (BigInteger.ZERO.equals(bg)) {
616 throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
617 }
618 return new BigFraction(numerator, denominator.multiply(bg));
619 }
620
621 /**
622 * <p>
623 * Divide the value of this fraction by the passed {@code int}, ie
624 * {@code this * 1 / i}, returning the result in reduced form.
625 * </p>
626 *
627 * @param i the {@code int} to divide by
628 * @return a {@link BigFraction} instance with the resulting values
629 * @throws MathArithmeticException if the fraction to divide by is zero
630 */
631 public BigFraction divide(final int i) {
632 return divide(BigInteger.valueOf(i));
633 }
634
635 /**
636 * <p>
637 * Divide the value of this fraction by the passed {@code long}, ie
638 * {@code this * 1 / l}, returning the result in reduced form.
639 * </p>
640 *
641 * @param l the {@code long} to divide by
642 * @return a {@link BigFraction} instance with the resulting values
643 * @throws MathArithmeticException if the fraction to divide by is zero
644 */
645 public BigFraction divide(final long l) {
646 return divide(BigInteger.valueOf(l));
647 }
648
649 /**
650 * <p>
651 * Divide the value of this fraction by another, returning the result in
652 * reduced form.
653 * </p>
654 *
655 * @param fraction Fraction to divide by, must not be {@code null}.
656 * @return a {@link BigFraction} instance with the resulting values.
657 * @throws NullArgumentException if the {@code fraction} is {@code null}.
658 * @throws MathArithmeticException if the fraction to divide by is zero
659 */
660 public BigFraction divide(final BigFraction fraction) {
661 if (fraction == null) {
662 throw new NullArgumentException(LocalizedFormats.FRACTION);
663 }
664 if (BigInteger.ZERO.equals(fraction.numerator)) {
665 throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
666 }
667
668 return multiply(fraction.reciprocal());
669 }
670
671 /**
672 * <p>
673 * Gets the fraction as a <tt>double</tt>. This calculates the fraction as
674 * the numerator divided by denominator.
675 * </p>
676 *
677 * @return the fraction as a <tt>double</tt>
678 * @see java.lang.Number#doubleValue()
679 */
680 @Override
681 public double doubleValue() {
682 double result = numerator.doubleValue() / denominator.doubleValue();
683 if (Double.isNaN(result)) {
684 // Numerator and/or denominator must be out of range:
685 // Calculate how far to shift them to put them in range.
686 int shift = Math.max(numerator.bitLength(),
687 denominator.bitLength()) - FastMath.getExponent(Double.MAX_VALUE);
688 result = numerator.shiftRight(shift).doubleValue() /
689 denominator.shiftRight(shift).doubleValue();
690 }
691 return result;
692 }
693
694 /**
695 * <p>
696 * Test for the equality of two fractions. If the lowest term numerator and
697 * denominators are the same for both fractions, the two fractions are
698 * considered to be equal.
699 * </p>
700 *
701 * @param other
702 * fraction to test for equality to this fraction, can be
703 * <code>null</code>.
704 * @return true if two fractions are equal, false if object is
705 * <code>null</code>, not an instance of {@link BigFraction}, or not
706 * equal to this fraction instance.
707 * @see java.lang.Object#equals(java.lang.Object)
708 */
709 @Override
710 public boolean equals(final Object other) {
711 boolean ret = false;
712
713 if (this == other) {
714 ret = true;
715 } else if (other instanceof BigFraction) {
716 BigFraction rhs = ((BigFraction) other).reduce();
717 BigFraction thisOne = this.reduce();
718 ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator);
719 }
720
721 return ret;
722 }
723
724 /**
725 * <p>
726 * Gets the fraction as a <tt>float</tt>. This calculates the fraction as
727 * the numerator divided by denominator.
728 * </p>
729 *
730 * @return the fraction as a <tt>float</tt>.
731 * @see java.lang.Number#floatValue()
732 */
733 @Override
734 public float floatValue() {
735 float result = numerator.floatValue() / denominator.floatValue();
736 if (Double.isNaN(result)) {
737 // Numerator and/or denominator must be out of range:
738 // Calculate how far to shift them to put them in range.
739 int shift = Math.max(numerator.bitLength(),
740 denominator.bitLength()) - FastMath.getExponent(Float.MAX_VALUE);
741 result = numerator.shiftRight(shift).floatValue() /
742 denominator.shiftRight(shift).floatValue();
743 }
744 return result;
745 }
746
747 /**
748 * <p>
749 * Access the denominator as a <code>BigInteger</code>.
750 * </p>
751 *
752 * @return the denominator as a <code>BigInteger</code>.
753 */
754 public BigInteger getDenominator() {
755 return denominator;
756 }
757
758 /**
759 * <p>
760 * Access the denominator as a <tt>int</tt>.
761 * </p>
762 *
763 * @return the denominator as a <tt>int</tt>.
764 */
765 public int getDenominatorAsInt() {
766 return denominator.intValue();
767 }
768
769 /**
770 * <p>
771 * Access the denominator as a <tt>long</tt>.
772 * </p>
773 *
774 * @return the denominator as a <tt>long</tt>.
775 */
776 public long getDenominatorAsLong() {
777 return denominator.longValue();
778 }
779
780 /**
781 * <p>
782 * Access the numerator as a <code>BigInteger</code>.
783 * </p>
784 *
785 * @return the numerator as a <code>BigInteger</code>.
786 */
787 public BigInteger getNumerator() {
788 return numerator;
789 }
790
791 /**
792 * <p>
793 * Access the numerator as a <tt>int</tt>.
794 * </p>
795 *
796 * @return the numerator as a <tt>int</tt>.
797 */
798 public int getNumeratorAsInt() {
799 return numerator.intValue();
800 }
801
802 /**
803 * <p>
804 * Access the numerator as a <tt>long</tt>.
805 * </p>
806 *
807 * @return the numerator as a <tt>long</tt>.
808 */
809 public long getNumeratorAsLong() {
810 return numerator.longValue();
811 }
812
813 /**
814 * <p>
815 * Gets a hashCode for the fraction.
816 * </p>
817 *
818 * @return a hash code value for this object.
819 * @see java.lang.Object#hashCode()
820 */
821 @Override
822 public int hashCode() {
823 return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
824 }
825
826 /**
827 * <p>
828 * Gets the fraction as an <tt>int</tt>. This returns the whole number part
829 * of the fraction.
830 * </p>
831 *
832 * @return the whole number fraction part.
833 * @see java.lang.Number#intValue()
834 */
835 @Override
836 public int intValue() {
837 return numerator.divide(denominator).intValue();
838 }
839
840 /**
841 * <p>
842 * Gets the fraction as a <tt>long</tt>. This returns the whole number part
843 * of the fraction.
844 * </p>
845 *
846 * @return the whole number fraction part.
847 * @see java.lang.Number#longValue()
848 */
849 @Override
850 public long longValue() {
851 return numerator.divide(denominator).longValue();
852 }
853
854 /**
855 * <p>
856 * Multiplies the value of this fraction by the passed
857 * <code>BigInteger</code>, returning the result in reduced form.
858 * </p>
859 *
860 * @param bg the {@code BigInteger} to multiply by.
861 * @return a {@code BigFraction} instance with the resulting values.
862 * @throws NullArgumentException if {@code bg} is {@code null}.
863 */
864 public BigFraction multiply(final BigInteger bg) {
865 if (bg == null) {
866 throw new NullArgumentException();
867 }
868 return new BigFraction(bg.multiply(numerator), denominator);
869 }
870
871 /**
872 * <p>
873 * Multiply the value of this fraction by the passed <tt>int</tt>, returning
874 * the result in reduced form.
875 * </p>
876 *
877 * @param i
878 * the <tt>int</tt> to multiply by.
879 * @return a {@link BigFraction} instance with the resulting values.
880 */
881 public BigFraction multiply(final int i) {
882 return multiply(BigInteger.valueOf(i));
883 }
884
885 /**
886 * <p>
887 * Multiply the value of this fraction by the passed <tt>long</tt>,
888 * returning the result in reduced form.
889 * </p>
890 *
891 * @param l
892 * the <tt>long</tt> to multiply by.
893 * @return a {@link BigFraction} instance with the resulting values.
894 */
895 public BigFraction multiply(final long l) {
896 return multiply(BigInteger.valueOf(l));
897 }
898
899 /**
900 * <p>
901 * Multiplies the value of this fraction by another, returning the result in
902 * reduced form.
903 * </p>
904 *
905 * @param fraction Fraction to multiply by, must not be {@code null}.
906 * @return a {@link BigFraction} instance with the resulting values.
907 * @throws NullArgumentException if {@code fraction} is {@code null}.
908 */
909 public BigFraction multiply(final BigFraction fraction) {
910 if (fraction == null) {
911 throw new NullArgumentException(LocalizedFormats.FRACTION);
912 }
913 if (numerator.equals(BigInteger.ZERO) ||
914 fraction.numerator.equals(BigInteger.ZERO)) {
915 return ZERO;
916 }
917 return new BigFraction(numerator.multiply(fraction.numerator),
918 denominator.multiply(fraction.denominator));
919 }
920
921 /**
922 * <p>
923 * Return the additive inverse of this fraction, returning the result in
924 * reduced form.
925 * </p>
926 *
927 * @return the negation of this fraction.
928 */
929 public BigFraction negate() {
930 return new BigFraction(numerator.negate(), denominator);
931 }
932
933 /**
934 * <p>
935 * Gets the fraction percentage as a <tt>double</tt>. This calculates the
936 * fraction as the numerator divided by denominator multiplied by 100.
937 * </p>
938 *
939 * @return the fraction percentage as a <tt>double</tt>.
940 */
941 public double percentageValue() {
942 return multiply(ONE_HUNDRED).doubleValue();
943 }
944
945 /**
946 * <p>
947 * Returns a {@code BigFraction} whose value is
948 * {@code (this<sup>exponent</sup>)}, returning the result in reduced form.
949 * </p>
950 *
951 * @param exponent
952 * exponent to which this {@code BigFraction} is to be
953 * raised.
954 * @return <tt>this<sup>exponent</sup></tt>.
955 */
956 public BigFraction pow(final int exponent) {
957 if (exponent < 0) {
958 return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
959 }
960 return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
961 }
962
963 /**
964 * <p>
965 * Returns a <code>BigFraction</code> whose value is
966 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
967 * </p>
968 *
969 * @param exponent
970 * exponent to which this <code>BigFraction</code> is to be raised.
971 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
972 */
973 public BigFraction pow(final long exponent) {
974 if (exponent < 0) {
975 return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
976 ArithmeticUtils.pow(numerator, -exponent));
977 }
978 return new BigFraction(ArithmeticUtils.pow(numerator, exponent),
979 ArithmeticUtils.pow(denominator, exponent));
980 }
981
982 /**
983 * <p>
984 * Returns a <code>BigFraction</code> whose value is
985 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
986 * </p>
987 *
988 * @param exponent
989 * exponent to which this <code>BigFraction</code> is to be raised.
990 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
991 */
992 public BigFraction pow(final BigInteger exponent) {
993 if (exponent.compareTo(BigInteger.ZERO) < 0) {
994 final BigInteger eNeg = exponent.negate();
995 return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
996 ArithmeticUtils.pow(numerator, eNeg));
997 }
998 return new BigFraction(ArithmeticUtils.pow(numerator, exponent),
999 ArithmeticUtils.pow(denominator, exponent));
1000 }
1001
1002 /**
1003 * <p>
1004 * Returns a <code>double</code> whose value is
1005 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
1006 * </p>
1007 *
1008 * @param exponent
1009 * exponent to which this <code>BigFraction</code> is to be raised.
1010 * @return <tt>this<sup>exponent</sup></tt>.
1011 */
1012 public double pow(final double exponent) {
1013 return FastMath.pow(numerator.doubleValue(), exponent) /
1014 FastMath.pow(denominator.doubleValue(), exponent);
1015 }
1016
1017 /**
1018 * <p>
1019 * Return the multiplicative inverse of this fraction.
1020 * </p>
1021 *
1022 * @return the reciprocal fraction.
1023 */
1024 public BigFraction reciprocal() {
1025 return new BigFraction(denominator, numerator);
1026 }
1027
1028 /**
1029 * <p>
1030 * Reduce this <code>BigFraction</code> to its lowest terms.
1031 * </p>
1032 *
1033 * @return the reduced <code>BigFraction</code>. It doesn't change anything if
1034 * the fraction can be reduced.
1035 */
1036 public BigFraction reduce() {
1037 final BigInteger gcd = numerator.gcd(denominator);
1038 return new BigFraction(numerator.divide(gcd), denominator.divide(gcd));
1039 }
1040
1041 /**
1042 * <p>
1043 * Subtracts the value of an {@link BigInteger} from the value of this
1044 * {@code BigFraction}, returning the result in reduced form.
1045 * </p>
1046 *
1047 * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
1048 * @return a {@code BigFraction} instance with the resulting values.
1049 * @throws NullArgumentException if the {@link BigInteger} is {@code null}.
1050 */
1051 public BigFraction subtract(final BigInteger bg) {
1052 if (bg == null) {
1053 throw new NullArgumentException();
1054 }
1055 return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
1056 }
1057
1058 /**
1059 * <p>
1060 * Subtracts the value of an {@code integer} from the value of this
1061 * {@code BigFraction}, returning the result in reduced form.
1062 * </p>
1063 *
1064 * @param i the {@code integer} to subtract.
1065 * @return a {@code BigFraction} instance with the resulting values.
1066 */
1067 public BigFraction subtract(final int i) {
1068 return subtract(BigInteger.valueOf(i));
1069 }
1070
1071 /**
1072 * <p>
1073 * Subtracts the value of a {@code long} from the value of this
1074 * {@code BigFraction}, returning the result in reduced form.
1075 * </p>
1076 *
1077 * @param l the {@code long} to subtract.
1078 * @return a {@code BigFraction} instance with the resulting values.
1079 */
1080 public BigFraction subtract(final long l) {
1081 return subtract(BigInteger.valueOf(l));
1082 }
1083
1084 /**
1085 * <p>
1086 * Subtracts the value of another fraction from the value of this one,
1087 * returning the result in reduced form.
1088 * </p>
1089 *
1090 * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
1091 * @return a {@link BigFraction} instance with the resulting values
1092 * @throws NullArgumentException if the {@code fraction} is {@code null}.
1093 */
1094 public BigFraction subtract(final BigFraction fraction) {
1095 if (fraction == null) {
1096 throw new NullArgumentException(LocalizedFormats.FRACTION);
1097 }
1098 if (ZERO.equals(fraction)) {
1099 return this;
1100 }
1101
1102 BigInteger num = null;
1103 BigInteger den = null;
1104 if (denominator.equals(fraction.denominator)) {
1105 num = numerator.subtract(fraction.numerator);
1106 den = denominator;
1107 } else {
1108 num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
1109 den = denominator.multiply(fraction.denominator);
1110 }
1111 return new BigFraction(num, den);
1112
1113 }
1114
1115 /**
1116 * <p>
1117 * Returns the <code>String</code> representing this fraction, ie
1118 * "num / dem" or just "num" if the denominator is one.
1119 * </p>
1120 *
1121 * @return a string representation of the fraction.
1122 * @see java.lang.Object#toString()
1123 */
1124 @Override
1125 public String toString() {
1126 String str = null;
1127 if (BigInteger.ONE.equals(denominator)) {
1128 str = numerator.toString();
1129 } else if (BigInteger.ZERO.equals(numerator)) {
1130 str = "0";
1131 } else {
1132 str = numerator + " / " + denominator;
1133 }
1134 return str;
1135 }
1136
1137 /** {@inheritDoc} */
1138 public BigFractionField getField() {
1139 return BigFractionField.getInstance();
1140 }
1141
1142 }