source: src/main/java/agents/org/apache/commons/math/fraction/BigFraction.java

Last change on this file was 1, checked in by Wouter Pasman, 7 years ago

Initial import : Genius 9.0.0

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