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 */
17 package org.apache.commons.numbers.fraction;
18
19 import java.io.Serializable;
20 import org.apache.commons.numbers.core.ArithmeticUtils;
21 import org.apache.commons.numbers.core.NativeOperators;
22
23 /**
24 * Representation of a rational number.
25 *
26 * <p>The number is expressed as the quotient {@code p/q} of two 32-bit integers,
27 * a numerator {@code p} and a non-zero denominator {@code q}.
28 *
29 * <p>This class is immutable.
30 *
31 * <a href="https://en.wikipedia.org/wiki/Rational_number">Rational number</a>
32 */
33 public final class Fraction
34 extends Number
35 implements Comparable<Fraction>,
36 NativeOperators<Fraction>,
37 Serializable {
38 /** A fraction representing "0". */
39 public static final Fraction ZERO = new Fraction(0);
40
41 /** A fraction representing "1". */
42 public static final Fraction ONE = new Fraction(1);
43
44 /** Serializable version identifier. */
45 private static final long serialVersionUID = 20190701L;
46
47 /** The default epsilon used for convergence. */
48 private static final double DEFAULT_EPSILON = 1e-5;
49
50 /** The default iterations used for convergence. */
51 private static final int DEFAULT_MAX_ITERATIONS = 100;
52
53 /** Message for non-finite input double argument to factory constructors. */
54 private static final String NOT_FINITE = "Not finite: ";
55
56 /** The overflow limit for conversion from a double (2^31). */
57 private static final long OVERFLOW = 1L << 31;
58
59 /** The numerator of this fraction reduced to lowest terms. */
60 private final int numerator;
61
62 /** The denominator of this fraction reduced to lowest terms. */
63 private final int denominator;
64
65 /**
66 * Private constructor: Instances are created using factory methods.
67 *
68 * <p>This constructor should only be invoked when the fraction is known
69 * to be non-zero; otherwise use {@link #ZERO}. This avoids creating
70 * the zero representation {@code 0 / -1}.
71 *
72 * @param num Numerator.
73 * @param den Denominator.
74 * @throws ArithmeticException if the denominator is {@code zero}.
75 */
76 private Fraction(int num, int den) {
77 if (den == 0) {
78 throw new FractionException(FractionException.ERROR_ZERO_DENOMINATOR);
79 }
80
81 if (num == den) {
82 numerator = 1;
83 denominator = 1;
84 } else {
85 // Reduce numerator (p) and denominator (q) by greatest common divisor.
86 final int p;
87 final int q;
88
89 // If num and den are both 2^-31, or if one is 0 and the other is 2^-31,
90 // the calculation of the gcd below will fail. Ensure that this does not
91 // happen by dividing both by 2 in case both are even.
92 if (((num | den) & 1) == 0) {
93 p = num >> 1;
94 q = den >> 1;
95 } else {
96 p = num;
97 q = den;
98 }
99
100 // Will not throw.
101 // Cannot return 0 as gcd(0, 0) has been eliminated.
102 final int d = ArithmeticUtils.gcd(p, q);
103 numerator = p / d;
104 denominator = q / d;
105 }
106 }
107
108 /**
109 * Private constructor: Instances are created using factory methods.
110 *
111 * <p>This sets the denominator to 1.
112 *
113 * @param num Numerator.
114 */
115 private Fraction(int num) {
116 numerator = num;
117 denominator = 1;
118 }
119
120 /**
121 * Create a fraction given the double value and either the maximum error
122 * allowed or the maximum number of denominator digits.
123 *
124 * <p>
125 * NOTE: This constructor is called with:
126 * <ul>
127 * <li>EITHER a valid epsilon value and the maxDenominator set to
128 * Integer.MAX_VALUE (that way the maxDenominator has no effect)</li>
129 * <li>OR a valid maxDenominator value and the epsilon value set to
130 * zero (that way epsilon only has effect if there is an exact
131 * match before the maxDenominator value is reached).</li>
132 * </ul>
133 * <p>
134 * It has been done this way so that the same code can be reused for
135 * both scenarios. However this could be confusing to users if it
136 * were part of the public API and this method should therefore remain
137 * PRIVATE.
138 * </p>
139 *
140 * <p>
141 * See JIRA issue ticket MATH-181 for more details:
142 * https://issues.apache.org/jira/browse/MATH-181
143 * </p>
144 *
145 * <p>
146 * Warning: This conversion assumes the value is not zero.
147 * </p>
148 *
149 * @param value Value to convert to a fraction. Must not be zero.
150 * @param epsilon Maximum error allowed.
151 * The resulting fraction is within {@code epsilon} of {@code value},
152 * in absolute terms.
153 * @param maxDenominator Maximum denominator value allowed.
154 * @param maxIterations Maximum number of convergents.
155 * @throws IllegalArgumentException if the given {@code value} is NaN or infinite.
156 * @throws ArithmeticException if the continued fraction failed to converge.
157 */
158 private Fraction(final double value,
159 final double epsilon,
160 final int maxDenominator,
161 final int maxIterations) {
162 if (!Double.isFinite(value)) {
163 throw new IllegalArgumentException(NOT_FINITE + value);
164 }
165
166 // Remove sign, this is restored at the end.
167 // (Assumes the value is not zero and thus signum(value) is not zero).
168 final double absValue = Math.abs(value);
169 double r0 = absValue;
170 long a0 = (long) Math.floor(r0);
171 if (a0 > OVERFLOW) {
172 throw new FractionException(FractionException.ERROR_CONVERSION_OVERFLOW, value, a0, 1);
173 }
174
175 // check for (almost) integer arguments, which should not go to iterations.
176 if (r0 - a0 <= epsilon) {
177 int num = (int) a0;
178 int den = 1;
179 // Restore the sign.
180 if (Math.signum(num) != Math.signum(value)) {
181 if (num == Integer.MIN_VALUE) {
182 den = -den;
183 } else {
184 num = -num;
185 }
186 }
187 this.numerator = num;
188 this.denominator = den;
189 return;
190 }
191
192 // Support 2^31 as maximum denominator.
193 // This is negative as an integer so convert to long.
194 final long maxDen = Math.abs((long) maxDenominator);
195
196 long p0 = 1;
197 long q0 = 0;
198 long p1 = a0;
199 long q1 = 1;
200
201 long p2;
202 long q2;
203
204 int n = 0;
205 boolean stop = false;
206 do {
207 ++n;
208 final double r1 = 1.0 / (r0 - a0);
209 final long a1 = (long) Math.floor(r1);
210 p2 = (a1 * p1) + p0;
211 q2 = (a1 * q1) + q0;
212
213 if (Long.compareUnsigned(p2, OVERFLOW) > 0 ||
214 Long.compareUnsigned(q2, OVERFLOW) > 0) {
215 // In maxDenominator mode, fall-back to the previous valid fraction.
216 if (epsilon == 0.0) {
217 p2 = p1;
218 q2 = q1;
219 break;
220 }
221 throw new FractionException(FractionException.ERROR_CONVERSION_OVERFLOW, value, p2, q2);
222 }
223
224 final double convergent = (double) p2 / q2;
225 if (n < maxIterations &&
226 Math.abs(convergent - absValue) > epsilon &&
227 q2 < maxDen) {
228 p0 = p1;
229 p1 = p2;
230 q0 = q1;
231 q1 = q2;
232 a0 = a1;
233 r0 = r1;
234 } else {
235 stop = true;
236 }
237 } while (!stop);
238
239 if (n >= maxIterations) {
240 throw new FractionException(FractionException.ERROR_CONVERSION, value, maxIterations);
241 }
242
243 // Use p2 / q2 or p1 / q1 if q2 has grown too large in maxDenominator mode
244 // Note: Conversion of long 2^31 to an integer will create a negative. This could
245 // be either the numerator or denominator. This is handled by restoring the sign.
246 int num;
247 int den;
248 if (q2 <= maxDen) {
249 num = (int) p2;
250 den = (int) q2;
251 } else {
252 num = (int) p1;
253 den = (int) q1;
254 }
255
256 // Restore the sign.
257 if (Math.signum(num) * Math.signum(den) != Math.signum(value)) {
258 if (num == Integer.MIN_VALUE) {
259 den = -den;
260 } else {
261 num = -num;
262 }
263 }
264
265 this.numerator = num;
266 this.denominator = den;
267 }
268
269 /**
270 * Create a fraction given the double value.
271 *
272 * @param value Value to convert to a fraction.
273 * @throws IllegalArgumentException if the given {@code value} is NaN or infinite.
274 * @throws ArithmeticException if the continued fraction failed to converge.
275 * @return a new instance.
276 */
277 public static Fraction from(final double value) {
278 return from(value, DEFAULT_EPSILON, DEFAULT_MAX_ITERATIONS);
279 }
280
281 /**
282 * Create a fraction given the double value and maximum error allowed.
283 *
284 * <p>
285 * References:
286 * <ul>
287 * <li><a href="https://mathworld.wolfram.com/ContinuedFraction.html">
288 * Continued Fraction</a> equations (11) and (22)-(26)</li>
289 * </ul>
290 *
291 * @param value Value to convert to a fraction.
292 * @param epsilon Maximum error allowed. The resulting fraction is within
293 * {@code epsilon} of {@code value}, in absolute terms.
294 * @param maxIterations Maximum number of convergents.
295 * @throws IllegalArgumentException if the given {@code value} is NaN or infinite;
296 * {@code epsilon} is not positive; or {@code maxIterations < 1}.
297 * @throws ArithmeticException if the continued fraction failed to converge.
298 * @return a new instance.
299 */
300 public static Fraction from(final double value,
301 final double epsilon,
302 final int maxIterations) {
303 if (value == 0) {
304 return ZERO;
305 }
306 if (maxIterations < 1) {
307 throw new IllegalArgumentException("Max iterations must be strictly positive: " + maxIterations);
308 }
309 if (epsilon >= 0) {
310 return new Fraction(value, epsilon, Integer.MIN_VALUE, maxIterations);
311 }
312 throw new IllegalArgumentException("Epsilon must be positive: " + maxIterations);
313 }
314
315 /**
316 * Create a fraction given the double value and maximum denominator.
317 *
318 * <p>
319 * References:
320 * <ul>
321 * <li><a href="https://mathworld.wolfram.com/ContinuedFraction.html">
322 * Continued Fraction</a> equations (11) and (22)-(26)</li>
323 * </ul>
324 *
325 * <p>Note: The magnitude of the {@code maxDenominator} is used allowing use of
326 * {@link Integer#MIN_VALUE} for a supported maximum denominator of 2<sup>31</sup>.
327 *
328 * @param value Value to convert to a fraction.
329 * @param maxDenominator Maximum allowed value for denominator.
330 * @throws IllegalArgumentException if the given {@code value} is NaN or infinite
331 * or {@code maxDenominator} is zero.
332 * @throws ArithmeticException if the continued fraction failed to converge.
333 * @return a new instance.
334 */
335 public static Fraction from(final double value,
336 final int maxDenominator) {
337 if (value == 0) {
338 return ZERO;
339 }
340 if (maxDenominator == 0) {
341 // Re-use the zero denominator message
342 throw new IllegalArgumentException(FractionException.ERROR_ZERO_DENOMINATOR);
343 }
344 return new Fraction(value, 0, maxDenominator, DEFAULT_MAX_ITERATIONS);
345 }
346
347 /**
348 * Create a fraction given the numerator. The denominator is {@code 1}.
349 *
350 * @param num Numerator.
351 * @return a new instance.
352 */
353 public static Fraction of(final int num) {
354 if (num == 0) {
355 return ZERO;
356 }
357 return new Fraction(num);
358 }
359
360 /**
361 * Create a fraction given the numerator and denominator.
362 * The fraction is reduced to lowest terms.
363 *
364 * @param num Numerator.
365 * @param den Denominator.
366 * @throws ArithmeticException if the denominator is {@code zero}.
367 * @return a new instance.
368 */
369 public static Fraction of(final int num, final int den) {
370 if (num == 0) {
371 return ZERO;
372 }
373 return new Fraction(num, den);
374 }
375
376 /**
377 * Returns a {@code Fraction} instance representing the specified string {@code s}.
378 *
379 * <p>If {@code s} is {@code null}, then a {@code NullPointerException} is thrown.
380 *
381 * <p>The string must be in a format compatible with that produced by
382 * {@link #toString() Fraction.toString()}.
383 * The format expects an integer optionally followed by a {@code '/'} character and
384 * and second integer. Leading and trailing spaces are allowed around each numeric part.
385 * Each numeric part is parsed using {@link Integer#parseInt(String)}. The parts
386 * are interpreted as the numerator and optional denominator of the fraction. If absent
387 * the denominator is assumed to be "1".
388 *
389 * <p>Examples of valid strings and the equivalent {@code Fraction} are shown below:
390 *
391 * <pre>
392 * "0" = Fraction.of(0)
393 * "42" = Fraction.of(42)
394 * "0 / 1" = Fraction.of(0, 1)
395 * "1 / 3" = Fraction.of(1, 3)
396 * "-4 / 13" = Fraction.of(-4, 13)</pre>
397 *
398 * <p>Note: The fraction is returned in reduced form and the numerator and denominator
399 * may not match the values in the input string. For this reason the result of
400 * {@code Fraction.parse(s).toString().equals(s)} may not be {@code true}.
401 *
402 * @param s String representation.
403 * @return an instance.
404 * @throws NullPointerException if the string is null.
405 * @throws NumberFormatException if the string does not contain a parsable fraction.
406 * @see Integer#parseInt(String)
407 * @see #toString()
408 */
409 public static Fraction parse(String s) {
410 final String stripped = s.replace(",", "");
411 final int slashLoc = stripped.indexOf('/');
412 // if no slash, parse as single number
413 if (slashLoc == -1) {
414 return of(Integer.parseInt(stripped.trim()));
415 }
416 final int num = Integer.parseInt(stripped.substring(0, slashLoc).trim());
417 final int denom = Integer.parseInt(stripped.substring(slashLoc + 1).trim());
418 return of(num, denom);
419 }
420
421 @Override
422 public Fraction zero() {
423 return ZERO;
424 }
425
426 /**
427 * {@inheritDoc}
428 *
429 * @since 1.2
430 */
431 @Override
432 public boolean isZero() {
433 return numerator == 0;
434 }
435
436 @Override
437 public Fraction one() {
438 return ONE;
439 }
440
441 /**
442 * {@inheritDoc}
443 *
444 * @since 1.2
445 */
446 @Override
447 public boolean isOne() {
448 return numerator == denominator;
449 }
450
451 /**
452 * Access the numerator as an {@code int}.
453 *
454 * @return the numerator as an {@code int}.
455 */
456 public int getNumerator() {
457 return numerator;
458 }
459
460 /**
461 * Access the denominator as an {@code int}.
462 *
463 * @return the denominator as an {@code int}.
464 */
465 public int getDenominator() {
466 return denominator;
467 }
468
469 /**
470 * Retrieves the sign of this fraction.
471 *
472 * @return -1 if the value is strictly negative, 1 if it is strictly
473 * positive, 0 if it is 0.
474 */
475 public int signum() {
476 return Integer.signum(numerator) * Integer.signum(denominator);
477 }
478
479 /**
480 * Returns the absolute value of this fraction.
481 *
482 * @return the absolute value.
483 */
484 public Fraction abs() {
485 return signum() >= 0 ?
486 this :
487 negate();
488 }
489
490 @Override
491 public Fraction negate() {
492 return numerator == Integer.MIN_VALUE ?
493 new Fraction(numerator, -denominator) :
494 new Fraction(-numerator, denominator);
495 }
496
497 /**
498 * {@inheritDoc}
499 *
500 * <p>Raises an exception if the fraction is equal to zero.
501 *
502 * @throws ArithmeticException if the current numerator is {@code zero}
503 */
504 @Override
505 public Fraction reciprocal() {
506 return new Fraction(denominator, numerator);
507 }
508
509 /**
510 * Returns the {@code double} value closest to this fraction.
511 * This calculates the fraction as numerator divided by denominator.
512 *
513 * @return the fraction as a {@code double}.
514 */
515 @Override
516 public double doubleValue() {
517 return numerator / (double) denominator;
518 }
519
520 /**
521 * Returns the {@code float} value closest to this fraction.
522 * This calculates the fraction as numerator divided by denominator.
523 *
524 * @return the fraction as a {@code float}.
525 */
526 @Override
527 public float floatValue() {
528 return (float) doubleValue();
529 }
530
531 /**
532 * Returns the whole number part of the fraction.
533 *
534 * @return the largest {@code int} value that is not larger than this fraction.
535 */
536 @Override
537 public int intValue() {
538 // Note: numerator / denominator fails for Integer.MIN_VALUE / -1.
539 // Casting the double value handles this case.
540 return (int) doubleValue();
541 }
542
543 /**
544 * Returns the whole number part of the fraction.
545 *
546 * @return the largest {@code long} value that is not larger than this fraction.
547 */
548 @Override
549 public long longValue() {
550 return (long) numerator / denominator;
551 }
552
553 /**
554 * Adds the specified {@code value} to this fraction, returning
555 * the result in reduced form.
556 *
557 * @param value Value to add.
558 * @return {@code this + value}.
559 * @throws ArithmeticException if the resulting numerator
560 * cannot be represented in an {@code int}.
561 */
562 public Fraction add(final int value) {
563 if (value == 0) {
564 return this;
565 }
566 if (isZero()) {
567 return new Fraction(value);
568 }
569 // Convert to numerator with same effective denominator
570 final long num = (long) value * denominator;
571 return of(Math.toIntExact(numerator + num), denominator);
572 }
573
574 /**
575 * Adds the specified {@code value} to this fraction, returning
576 * the result in reduced form.
577 *
578 * @param value Value to add.
579 * @return {@code this + value}.
580 * @throws ArithmeticException if the resulting numerator or denominator
581 * cannot be represented in an {@code int}.
582 */
583 @Override
584 public Fraction add(Fraction value) {
585 return addSub(value, true /* add */);
586 }
587
588 /**
589 * Subtracts the specified {@code value} from this fraction, returning
590 * the result in reduced form.
591 *
592 * @param value Value to subtract.
593 * @return {@code this - value}.
594 * @throws ArithmeticException if the resulting numerator
595 * cannot be represented in an {@code int}.
596 */
597 public Fraction subtract(final int value) {
598 if (value == 0) {
599 return this;
600 }
601 if (isZero()) {
602 // Special case for min value
603 return value == Integer.MIN_VALUE ?
604 new Fraction(Integer.MIN_VALUE, -1) :
605 new Fraction(-value);
606 }
607 // Convert to numerator with same effective denominator
608 final long num = (long) value * denominator;
609 return of(Math.toIntExact(numerator - num), denominator);
610 }
611
612 /**
613 * Subtracts the specified {@code value} from this fraction, returning
614 * the result in reduced form.
615 *
616 * @param value Value to subtract.
617 * @return {@code this - value}.
618 * @throws ArithmeticException if the resulting numerator or denominator
619 * cannot be represented in an {@code int}.
620 */
621 @Override
622 public Fraction subtract(Fraction value) {
623 return addSub(value, false /* subtract */);
624 }
625
626 /**
627 * Implements add and subtract using algorithm described in Knuth 4.5.1.
628 *
629 * @param value Fraction to add or subtract.
630 * @param isAdd Whether the operation is "add" or "subtract".
631 * @return a new instance.
632 * @throws ArithmeticException if the resulting numerator or denominator
633 * cannot be represented in an {@code int}.
634 */
635 private Fraction addSub(Fraction value, boolean isAdd) {
636 if (value.isZero()) {
637 return this;
638 }
639 // Zero is identity for addition.
640 if (isZero()) {
641 return isAdd ? value : value.negate();
642 }
643
644 /*
645 * Let the two fractions be u/u' and v/v', and d1 = gcd(u', v').
646 * First, compute t, defined as:
647 *
648 * t = u(v'/d1) +/- v(u'/d1)
649 */
650 final int d1 = ArithmeticUtils.gcd(denominator, value.denominator);
651 final long uvp = (long) numerator * (value.denominator / d1);
652 final long upv = (long) value.numerator * (denominator / d1);
653
654 /*
655 * The largest possible absolute value of a product of two ints is 2^62,
656 * which can only happen as a result of -2^31 * -2^31 = 2^62, so a
657 * product of -2^62 is not possible. It follows that (uvp - upv) cannot
658 * overflow, and (uvp + upv) could only overflow if uvp = upv = 2^62.
659 * But for this to happen, the terms u, v, v'/d1 and u'/d1 would all
660 * have to be -2^31, which is not possible because v'/d1 and u'/d1
661 * are necessarily coprime.
662 */
663 final long t = isAdd ? uvp + upv : uvp - upv;
664
665 /*
666 * Because u is coprime to u' and v is coprime to v', t is necessarily
667 * coprime to both v'/d1 and u'/d1. However, it might have a common
668 * factor with d1.
669 */
670 final long d2 = ArithmeticUtils.gcd(t, d1);
671 // result is (t/d2) / (u'/d1)(v'/d2)
672 return of(Math.toIntExact(t / d2),
673 Math.multiplyExact(denominator / d1,
674 value.denominator / (int) d2));
675 }
676
677 /**
678 * Multiply this fraction by the passed {@code value}, returning
679 * the result in reduced form.
680 *
681 * @param value Value to multiply by.
682 * @return {@code this * value}.
683 * @throws ArithmeticException if the resulting numerator
684 * cannot be represented in an {@code int}.
685 */
686 @Override
687 public Fraction multiply(final int value) {
688 if (value == 0 || isZero()) {
689 return ZERO;
690 }
691
692 // knuth 4.5.1
693 // Make sure we don't overflow unless the result *must* overflow.
694 // (see multiply(Fraction) using value / 1 as the argument).
695 final int d2 = ArithmeticUtils.gcd(value, denominator);
696 return new Fraction(Math.multiplyExact(numerator, value / d2),
697 denominator / d2);
698 }
699
700 /**
701 * Multiply this fraction by the passed {@code value}, returning
702 * the result in reduced form.
703 *
704 * @param value Value to multiply by.
705 * @return {@code this * value}.
706 * @throws ArithmeticException if the resulting numerator or denominator
707 * cannot be represented in an {@code int}.
708 */
709 @Override
710 public Fraction multiply(Fraction value) {
711 if (value.isZero() || isZero()) {
712 return ZERO;
713 }
714 return multiply(value.numerator, value.denominator);
715 }
716
717 /**
718 * Multiply this fraction by the passed fraction decomposed into a numerator and
719 * denominator, returning the result in reduced form.
720 *
721 * <p>This is a utility method to be used by multiply and divide. The decomposed
722 * fraction arguments and this fraction are not checked for zero.
723 *
724 * @param num Fraction numerator.
725 * @param den Fraction denominator.
726 * @return {@code this * num / den}.
727 * @throws ArithmeticException if the resulting numerator or denominator cannot
728 * be represented in an {@code int}.
729 */
730 private Fraction multiply(int num, int den) {
731 // knuth 4.5.1
732 // Make sure we don't overflow unless the result *must* overflow.
733 final int d1 = ArithmeticUtils.gcd(numerator, den);
734 final int d2 = ArithmeticUtils.gcd(num, denominator);
735 return new Fraction(Math.multiplyExact(numerator / d1, num / d2),
736 Math.multiplyExact(denominator / d2, den / d1));
737 }
738
739 /**
740 * Divide this fraction by the passed {@code value}, returning
741 * the result in reduced form.
742 *
743 * @param value Value to divide by
744 * @return {@code this / value}.
745 * @throws ArithmeticException if the value to divide by is zero
746 * or if the resulting numerator or denominator cannot be represented
747 * by an {@code int}.
748 */
749 public Fraction divide(final int value) {
750 if (value == 0) {
751 throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
752 }
753 if (isZero()) {
754 return ZERO;
755 }
756 // Multiply by reciprocal
757
758 // knuth 4.5.1
759 // Make sure we don't overflow unless the result *must* overflow.
760 // (see multiply(Fraction) using 1 / value as the argument).
761 final int d1 = ArithmeticUtils.gcd(numerator, value);
762 return new Fraction(numerator / d1,
763 Math.multiplyExact(denominator, value / d1));
764 }
765
766 /**
767 * Divide this fraction by the passed {@code value}, returning
768 * the result in reduced form.
769 *
770 * @param value Value to divide by
771 * @return {@code this / value}.
772 * @throws ArithmeticException if the value to divide by is zero
773 * or if the resulting numerator or denominator cannot be represented
774 * by an {@code int}.
775 */
776 @Override
777 public Fraction divide(Fraction value) {
778 if (value.isZero()) {
779 throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
780 }
781 if (isZero()) {
782 return ZERO;
783 }
784 // Multiply by reciprocal
785 return multiply(value.denominator, value.numerator);
786 }
787
788 /**
789 * Returns a {@code Fraction} whose value is
790 * <code>this<sup>exponent</sup></code>, returning the result in reduced form.
791 *
792 * @param exponent exponent to which this {@code Fraction} is to be raised.
793 * @return <code>this<sup>exponent</sup></code>.
794 * @throws ArithmeticException if the intermediate result would overflow.
795 */
796 @Override
797 public Fraction pow(final int exponent) {
798 if (exponent == 1) {
799 return this;
800 }
801 if (exponent == 0) {
802 return ONE;
803 }
804 if (isZero()) {
805 if (exponent < 0) {
806 throw new FractionException(FractionException.ERROR_ZERO_DENOMINATOR);
807 }
808 return ZERO;
809 }
810 if (exponent > 0) {
811 return new Fraction(ArithmeticUtils.pow(numerator, exponent),
812 ArithmeticUtils.pow(denominator, exponent));
813 }
814 if (exponent == -1) {
815 return this.reciprocal();
816 }
817 if (exponent == Integer.MIN_VALUE) {
818 // MIN_VALUE can't be negated
819 return new Fraction(ArithmeticUtils.pow(denominator, Integer.MAX_VALUE) * denominator,
820 ArithmeticUtils.pow(numerator, Integer.MAX_VALUE) * numerator);
821 }
822 return new Fraction(ArithmeticUtils.pow(denominator, -exponent),
823 ArithmeticUtils.pow(numerator, -exponent));
824 }
825
826 /**
827 * Returns the {@code String} representing this fraction.
828 * Uses:
829 * <ul>
830 * <li>{@code "0"} if {@code numerator} is zero.</li>
831 * <li>{@code "numerator"} if {@code denominator} is one.</li>
832 * <li>{@code "numerator / denominator"} for all other cases.</li>
833 * </ul>
834 *
835 * @return a string representation of the fraction.
836 */
837 @Override
838 public String toString() {
839 final String str;
840 if (isZero()) {
841 str = "0";
842 } else if (denominator == 1) {
843 str = Integer.toString(numerator);
844 } else {
845 str = numerator + " / " + denominator;
846 }
847 return str;
848 }
849
850 /**
851 * Compares this object with the specified object for order using the signed magnitude.
852 *
853 * @param other {@inheritDoc}
854 * @return {@inheritDoc}
855 */
856 @Override
857 public int compareTo(Fraction other) {
858 // Compute the sign of each part
859 final int lns = Integer.signum(numerator);
860 final int lds = Integer.signum(denominator);
861 final int rns = Integer.signum(other.numerator);
862 final int rds = Integer.signum(other.denominator);
863
864 final int lhsSigNum = lns * lds;
865 final int rhsSigNum = rns * rds;
866
867 if (lhsSigNum != rhsSigNum) {
868 return (lhsSigNum > rhsSigNum) ? 1 : -1;
869 }
870 // Same sign.
871 // Avoid a multiply if both fractions are zero
872 if (lhsSigNum == 0) {
873 return 0;
874 }
875 // Compare absolute magnitude.
876 // Multiplication by the signum is equal to the absolute.
877 final long nOd = ((long) numerator) * lns * other.denominator * rds;
878 final long dOn = ((long) denominator) * lds * other.numerator * rns;
879 return lhsSigNum > 0 ?
880 Long.compare(nOd, dOn) :
881 Long.compare(dOn, nOd);
882 }
883
884 /**
885 * Test for equality with another object. If the other object is a {@code Fraction} then a
886 * comparison is made of the sign and magnitude; otherwise {@code false} is returned.
887 *
888 * @param other {@inheritDoc}
889 * @return {@inheritDoc}
890 */
891 @Override
892 public boolean equals(Object other) {
893 if (this == other) {
894 return true;
895 }
896
897 if (other instanceof Fraction) {
898 // Since fractions are always in lowest terms, numerators and
899 // denominators can be compared directly for equality.
900 final Fraction rhs = (Fraction) other;
901 if (signum() == rhs.signum()) {
902 return Math.abs(numerator) == Math.abs(rhs.numerator) &&
903 Math.abs(denominator) == Math.abs(rhs.denominator);
904 }
905 }
906
907 return false;
908 }
909
910 @Override
911 public int hashCode() {
912 // Incorporate the sign and absolute values of the numerator and denominator.
913 // Equivalent to:
914 // int hash = 1;
915 // hash = 31 * hash + Math.abs(numerator);
916 // hash = 31 * hash + Math.abs(denominator);
917 // hash = hash * signum()
918 // Note: x * Integer.signum(x) == Math.abs(x).
919 final int numS = Integer.signum(numerator);
920 final int denS = Integer.signum(denominator);
921 return (31 * (31 + numerator * numS) + denominator * denS) * numS * denS;
922 }
923 }