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