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 */ 017package org.apache.commons.numbers.fraction; 018 019import java.io.Serializable; 020import org.apache.commons.numbers.core.ArithmeticUtils; 021import org.apache.commons.numbers.core.NativeOperators; 022 023/** 024 * Representation of a rational number. 025 * 026 * <p>The number is expressed as the quotient {@code p/q} of two 32-bit integers, 027 * a numerator {@code p} and a non-zero denominator {@code q}. 028 * 029 * <p>This class is immutable. 030 * 031 * <a href="https://en.wikipedia.org/wiki/Rational_number">Rational number</a> 032 */ 033public final class Fraction 034 extends Number 035 implements Comparable<Fraction>, 036 NativeOperators<Fraction>, 037 Serializable { 038 /** A fraction representing "0". */ 039 public static final Fraction ZERO = new Fraction(0); 040 041 /** A fraction representing "1". */ 042 public static final Fraction ONE = new Fraction(1); 043 044 /** Serializable version identifier. */ 045 private static final long serialVersionUID = 20190701L; 046 047 /** The default epsilon used for convergence. */ 048 private static final double DEFAULT_EPSILON = 1e-5; 049 050 /** The default iterations used for convergence. */ 051 private static final int DEFAULT_MAX_ITERATIONS = 100; 052 053 /** Message for non-finite input double argument to factory constructors. */ 054 private static final String NOT_FINITE = "Not finite: "; 055 056 /** The overflow limit for conversion from a double (2^31). */ 057 private static final long OVERFLOW = 1L << 31; 058 059 /** The numerator of this fraction reduced to lowest terms. */ 060 private final int numerator; 061 062 /** The denominator of this fraction reduced to lowest terms. */ 063 private final int denominator; 064 065 /** 066 * Private constructor: Instances are created using factory methods. 067 * 068 * <p>This constructor should only be invoked when the fraction is known 069 * to be non-zero; otherwise use {@link #ZERO}. This avoids creating 070 * the zero representation {@code 0 / -1}. 071 * 072 * @param num Numerator. 073 * @param den Denominator. 074 * @throws ArithmeticException if the denominator is {@code zero}. 075 */ 076 private Fraction(int num, int den) { 077 if (den == 0) { 078 throw new FractionException(FractionException.ERROR_ZERO_DENOMINATOR); 079 } 080 081 if (num == den) { 082 numerator = 1; 083 denominator = 1; 084 } else { 085 // Reduce numerator (p) and denominator (q) by greatest common divisor. 086 final int p; 087 final int q; 088 089 // If num and den are both 2^-31, or if one is 0 and the other is 2^-31, 090 // the calculation of the gcd below will fail. Ensure that this does not 091 // happen by dividing both by 2 in case both are even. 092 if (((num | den) & 1) == 0) { 093 p = num >> 1; 094 q = den >> 1; 095 } else { 096 p = num; 097 q = den; 098 } 099 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}