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