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.math3.fraction; 018 019import java.io.Serializable; 020import java.math.BigDecimal; 021import java.math.BigInteger; 022 023import org.apache.commons.math3.FieldElement; 024import org.apache.commons.math3.exception.MathArithmeticException; 025import org.apache.commons.math3.exception.MathIllegalArgumentException; 026import org.apache.commons.math3.exception.NullArgumentException; 027import org.apache.commons.math3.exception.ZeroException; 028import org.apache.commons.math3.exception.util.LocalizedFormats; 029import org.apache.commons.math3.util.ArithmeticUtils; 030import org.apache.commons.math3.util.FastMath; 031import org.apache.commons.math3.util.MathUtils; 032 033/** 034 * Representation of a rational number without any overflow. This class is 035 * immutable. 036 * 037 * @since 2.0 038 */ 039public class BigFraction 040 extends Number 041 implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable { 042 043 /** A fraction representing "2 / 1". */ 044 public static final BigFraction TWO = new BigFraction(2); 045 046 /** A fraction representing "1". */ 047 public static final BigFraction ONE = new BigFraction(1); 048 049 /** A fraction representing "0". */ 050 public static final BigFraction ZERO = new BigFraction(0); 051 052 /** A fraction representing "-1 / 1". */ 053 public static final BigFraction MINUS_ONE = new BigFraction(-1); 054 055 /** A fraction representing "4/5". */ 056 public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5); 057 058 /** A fraction representing "1/5". */ 059 public static final BigFraction ONE_FIFTH = new BigFraction(1, 5); 060 061 /** A fraction representing "1/2". */ 062 public static final BigFraction ONE_HALF = new BigFraction(1, 2); 063 064 /** A fraction representing "1/4". */ 065 public static final BigFraction ONE_QUARTER = new BigFraction(1, 4); 066 067 /** A fraction representing "1/3". */ 068 public static final BigFraction ONE_THIRD = new BigFraction(1, 3); 069 070 /** A fraction representing "3/5". */ 071 public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5); 072 073 /** A fraction representing "3/4". */ 074 public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4); 075 076 /** A fraction representing "2/5". */ 077 public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5); 078 079 /** A fraction representing "2/4". */ 080 public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4); 081 082 /** A fraction representing "2/3". */ 083 public static final BigFraction TWO_THIRDS = new BigFraction(2, 3); 084 085 /** Serializable version identifier. */ 086 private static final long serialVersionUID = -5630213147331578515L; 087 088 /** <code>BigInteger</code> representation of 100. */ 089 private static final BigInteger ONE_HUNDRED = BigInteger.valueOf(100); 090 091 /** The numerator. */ 092 private final BigInteger numerator; 093 094 /** The denominator. */ 095 private final BigInteger denominator; 096 097 /** 098 * <p> 099 * Create a {@link BigFraction} equivalent to the passed {@code BigInteger}, ie 100 * "num / 1". 101 * </p> 102 * 103 * @param num 104 * the numerator. 105 */ 106 public BigFraction(final BigInteger num) { 107 this(num, BigInteger.ONE); 108 } 109 110 /** 111 * Create a {@link BigFraction} given the numerator and denominator as 112 * {@code BigInteger}. The {@link BigFraction} is reduced to lowest terms. 113 * 114 * @param num the numerator, must not be {@code null}. 115 * @param den the denominator, must not be {@code null}. 116 * @throws ZeroException if the denominator is zero. 117 * @throws NullArgumentException if either of the arguments is null 118 */ 119 public BigFraction(BigInteger num, BigInteger den) { 120 MathUtils.checkNotNull(num, LocalizedFormats.NUMERATOR); 121 MathUtils.checkNotNull(den, LocalizedFormats.DENOMINATOR); 122 if (den.signum() == 0) { 123 throw new ZeroException(LocalizedFormats.ZERO_DENOMINATOR); 124 } 125 if (num.signum() == 0) { 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 (den.signum() == -1) { 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 double value 155 * exactly, considering its internal bits representation. This works for all 156 * values except NaN and infinities and does not requires any loop or 157 * 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 MathIllegalArgumentException if value is NaN or infinite 170 */ 171 public BigFraction(final double value) throws MathIllegalArgumentException { 172 if (Double.isNaN(value)) { 173 throw new MathIllegalArgumentException(LocalizedFormats.NAN_VALUE_CONVERSION); 174 } 175 if (Double.isInfinite(value)) { 176 throw new MathIllegalArgumentException(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 >>= 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 275 if (FastMath.abs(a0) > overflow) { 276 throw new FractionConversionException(value, a0, 1l); 277 } 278 279 // check for (almost) integer arguments, which should not go 280 // to iterations. 281 if (FastMath.abs(a0 - value) < epsilon) { 282 numerator = BigInteger.valueOf(a0); 283 denominator = BigInteger.ONE; 284 return; 285 } 286 287 long p0 = 1; 288 long q0 = 0; 289 long p1 = a0; 290 long q1 = 1; 291 292 long p2 = 0; 293 long q2 = 1; 294 295 int n = 0; 296 boolean stop = false; 297 do { 298 ++n; 299 final double r1 = 1.0 / (r0 - a0); 300 final long a1 = (long) FastMath.floor(r1); 301 p2 = (a1 * p1) + p0; 302 q2 = (a1 * q1) + q0; 303 if ((p2 > overflow) || (q2 > overflow)) { 304 // in maxDenominator mode, if the last fraction was very close to the actual value 305 // q2 may overflow in the next iteration; in this case return the last one. 306 if (epsilon == 0.0 && FastMath.abs(q1) < maxDenominator) { 307 break; 308 } 309 throw new FractionConversionException(value, p2, q2); 310 } 311 312 final double convergent = (double) p2 / (double) q2; 313 if ((n < maxIterations) && 314 (FastMath.abs(convergent - value) > epsilon) && 315 (q2 < maxDenominator)) { 316 p0 = p1; 317 p1 = p2; 318 q0 = q1; 319 q1 = q2; 320 a0 = a1; 321 r0 = r1; 322 } else { 323 stop = true; 324 } 325 } while (!stop); 326 327 if (n >= maxIterations) { 328 throw new FractionConversionException(value, maxIterations); 329 } 330 331 if (q2 < maxDenominator) { 332 numerator = BigInteger.valueOf(p2); 333 denominator = BigInteger.valueOf(q2); 334 } else { 335 numerator = BigInteger.valueOf(p1); 336 denominator = BigInteger.valueOf(q1); 337 } 338 } 339 340 /** 341 * Create a fraction given the double value and maximum denominator. 342 * <p> 343 * References: 344 * <ul> 345 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> 346 * Continued Fraction</a> equations (11) and (22)-(26)</li> 347 * </ul> 348 * </p> 349 * 350 * @param value 351 * the double value to convert to a fraction. 352 * @param maxDenominator 353 * The maximum allowed value for denominator. 354 * @throws FractionConversionException 355 * if the continued fraction failed to converge. 356 */ 357 public BigFraction(final double value, final int maxDenominator) 358 throws FractionConversionException { 359 this(value, 0, maxDenominator, 100); 360 } 361 362 /** 363 * <p> 364 * Create a {@link BigFraction} equivalent to the passed {@code int}, ie 365 * "num / 1". 366 * </p> 367 * 368 * @param num 369 * the numerator. 370 */ 371 public BigFraction(final int num) { 372 this(BigInteger.valueOf(num), BigInteger.ONE); 373 } 374 375 /** 376 * <p> 377 * Create a {@link BigFraction} given the numerator and denominator as simple 378 * {@code int}. The {@link BigFraction} is reduced to lowest terms. 379 * </p> 380 * 381 * @param num 382 * the numerator. 383 * @param den 384 * the denominator. 385 */ 386 public BigFraction(final int num, final int den) { 387 this(BigInteger.valueOf(num), BigInteger.valueOf(den)); 388 } 389 390 /** 391 * <p> 392 * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1". 393 * </p> 394 * 395 * @param num 396 * the numerator. 397 */ 398 public BigFraction(final long num) { 399 this(BigInteger.valueOf(num), BigInteger.ONE); 400 } 401 402 /** 403 * <p> 404 * Create a {@link BigFraction} given the numerator and denominator as simple 405 * {@code long}. The {@link BigFraction} is reduced to lowest terms. 406 * </p> 407 * 408 * @param num 409 * the numerator. 410 * @param den 411 * the denominator. 412 */ 413 public BigFraction(final long num, final long den) { 414 this(BigInteger.valueOf(num), BigInteger.valueOf(den)); 415 } 416 417 /** 418 * <p> 419 * Creates a <code>BigFraction</code> instance with the 2 parts of a fraction 420 * Y/Z. 421 * </p> 422 * 423 * <p> 424 * Any negative signs are resolved to be on the numerator. 425 * </p> 426 * 427 * @param numerator 428 * the numerator, for example the three in 'three sevenths'. 429 * @param denominator 430 * the denominator, for example the seven in 'three sevenths'. 431 * @return a new fraction instance, with the numerator and denominator 432 * reduced. 433 * @throws ArithmeticException 434 * if the denominator is <code>zero</code>. 435 */ 436 public static BigFraction getReducedFraction(final int numerator, 437 final int denominator) { 438 if (numerator == 0) { 439 return ZERO; // normalize zero. 440 } 441 442 return new BigFraction(numerator, denominator); 443 } 444 445 /** 446 * <p> 447 * Returns the absolute value of this {@link BigFraction}. 448 * </p> 449 * 450 * @return the absolute value as a {@link BigFraction}. 451 */ 452 public BigFraction abs() { 453 return (numerator.signum() == 1) ? this : negate(); 454 } 455 456 /** 457 * <p> 458 * Adds the value of this fraction to the passed {@link BigInteger}, 459 * returning the result in reduced form. 460 * </p> 461 * 462 * @param bg 463 * the {@link BigInteger} to add, must'nt be <code>null</code>. 464 * @return a <code>BigFraction</code> instance with the resulting values. 465 * @throws NullArgumentException 466 * if the {@link BigInteger} is <code>null</code>. 467 */ 468 public BigFraction add(final BigInteger bg) throws NullArgumentException { 469 MathUtils.checkNotNull(bg); 470 471 if (numerator.signum() == 0) { 472 return new BigFraction(bg); 473 } 474 if (bg.signum() == 0) { 475 return this; 476 } 477 478 return new BigFraction(numerator.add(denominator.multiply(bg)), denominator); 479 } 480 481 /** 482 * <p> 483 * Adds the value of this fraction to the passed {@code integer}, returning 484 * the result in reduced form. 485 * </p> 486 * 487 * @param i 488 * the {@code integer} to add. 489 * @return a <code>BigFraction</code> instance with the resulting values. 490 */ 491 public BigFraction add(final int i) { 492 return add(BigInteger.valueOf(i)); 493 } 494 495 /** 496 * <p> 497 * Adds the value of this fraction to the passed {@code long}, returning 498 * the result in reduced form. 499 * </p> 500 * 501 * @param l 502 * the {@code long} to add. 503 * @return a <code>BigFraction</code> instance with the resulting values. 504 */ 505 public BigFraction add(final long l) { 506 return add(BigInteger.valueOf(l)); 507 } 508 509 /** 510 * <p> 511 * Adds the value of this fraction to another, returning the result in 512 * reduced form. 513 * </p> 514 * 515 * @param fraction 516 * the {@link BigFraction} to add, must not be <code>null</code>. 517 * @return a {@link BigFraction} instance with the resulting values. 518 * @throws NullArgumentException if the {@link BigFraction} is {@code null}. 519 */ 520 public BigFraction add(final BigFraction fraction) { 521 if (fraction == null) { 522 throw new NullArgumentException(LocalizedFormats.FRACTION); 523 } 524 if (fraction.numerator.signum() == 0) { 525 return this; 526 } 527 if (numerator.signum() == 0) { 528 return fraction; 529 } 530 531 BigInteger num = null; 532 BigInteger den = null; 533 534 if (denominator.equals(fraction.denominator)) { 535 num = numerator.add(fraction.numerator); 536 den = denominator; 537 } else { 538 num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator)); 539 den = denominator.multiply(fraction.denominator); 540 } 541 542 if (num.signum() == 0) { 543 return ZERO; 544 } 545 546 return new BigFraction(num, den); 547 548 } 549 550 /** 551 * <p> 552 * Gets the fraction as a <code>BigDecimal</code>. This calculates the 553 * fraction as the numerator divided by denominator. 554 * </p> 555 * 556 * @return the fraction as a <code>BigDecimal</code>. 557 * @throws ArithmeticException 558 * if the exact quotient does not have a terminating decimal 559 * expansion. 560 * @see BigDecimal 561 */ 562 public BigDecimal bigDecimalValue() { 563 return new BigDecimal(numerator).divide(new BigDecimal(denominator)); 564 } 565 566 /** 567 * <p> 568 * Gets the fraction as a <code>BigDecimal</code> following the passed 569 * rounding mode. This calculates the fraction as the numerator divided by 570 * denominator. 571 * </p> 572 * 573 * @param roundingMode 574 * rounding mode to apply. see {@link BigDecimal} constants. 575 * @return the fraction as a <code>BigDecimal</code>. 576 * @throws IllegalArgumentException 577 * if {@code roundingMode} does not represent a valid rounding 578 * mode. 579 * @see BigDecimal 580 */ 581 public BigDecimal bigDecimalValue(final int roundingMode) { 582 return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode); 583 } 584 585 /** 586 * <p> 587 * Gets the fraction as a <code>BigDecimal</code> following the passed scale 588 * and rounding mode. This calculates the fraction as the numerator divided 589 * by denominator. 590 * </p> 591 * 592 * @param scale 593 * scale of the <code>BigDecimal</code> quotient to be returned. 594 * see {@link BigDecimal} for more information. 595 * @param roundingMode 596 * rounding mode to apply. see {@link BigDecimal} constants. 597 * @return the fraction as a <code>BigDecimal</code>. 598 * @see BigDecimal 599 */ 600 public BigDecimal bigDecimalValue(final int scale, final int roundingMode) { 601 return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode); 602 } 603 604 /** 605 * <p> 606 * Compares this object to another based on size. 607 * </p> 608 * 609 * @param object 610 * the object to compare to, must not be <code>null</code>. 611 * @return -1 if this is less than {@code object}, +1 if this is greater 612 * than {@code object}, 0 if they are equal. 613 * @see java.lang.Comparable#compareTo(java.lang.Object) 614 */ 615 public int compareTo(final BigFraction object) { 616 int lhsSigNum = numerator.signum(); 617 int rhsSigNum = object.numerator.signum(); 618 619 if (lhsSigNum != rhsSigNum) { 620 return (lhsSigNum > rhsSigNum) ? 1 : -1; 621 } 622 if (lhsSigNum == 0) { 623 return 0; 624 } 625 626 BigInteger nOd = numerator.multiply(object.denominator); 627 BigInteger dOn = denominator.multiply(object.numerator); 628 return nOd.compareTo(dOn); 629 } 630 631 /** 632 * <p> 633 * Divide the value of this fraction by the passed {@code BigInteger}, 634 * ie {@code this * 1 / bg}, returning the result in reduced form. 635 * </p> 636 * 637 * @param bg the {@code BigInteger} to divide by, must not be {@code null} 638 * @return a {@link BigFraction} instance with the resulting values 639 * @throws NullArgumentException if the {@code BigInteger} is {@code null} 640 * @throws MathArithmeticException if the fraction to divide by is zero 641 */ 642 public BigFraction divide(final BigInteger bg) { 643 if (bg == null) { 644 throw new NullArgumentException(LocalizedFormats.FRACTION); 645 } 646 if (bg.signum() == 0) { 647 throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); 648 } 649 if (numerator.signum() == 0) { 650 return ZERO; 651 } 652 return new BigFraction(numerator, denominator.multiply(bg)); 653 } 654 655 /** 656 * <p> 657 * Divide the value of this fraction by the passed {@code int}, ie 658 * {@code this * 1 / i}, returning the result in reduced form. 659 * </p> 660 * 661 * @param i the {@code int} to divide by 662 * @return a {@link BigFraction} instance with the resulting values 663 * @throws MathArithmeticException if the fraction to divide by is zero 664 */ 665 public BigFraction divide(final int i) { 666 return divide(BigInteger.valueOf(i)); 667 } 668 669 /** 670 * <p> 671 * Divide the value of this fraction by the passed {@code long}, ie 672 * {@code this * 1 / l}, returning the result in reduced form. 673 * </p> 674 * 675 * @param l the {@code long} to divide by 676 * @return a {@link BigFraction} instance with the resulting values 677 * @throws MathArithmeticException if the fraction to divide by is zero 678 */ 679 public BigFraction divide(final long l) { 680 return divide(BigInteger.valueOf(l)); 681 } 682 683 /** 684 * <p> 685 * Divide the value of this fraction by another, returning the result in 686 * reduced form. 687 * </p> 688 * 689 * @param fraction Fraction to divide by, must not be {@code null}. 690 * @return a {@link BigFraction} instance with the resulting values. 691 * @throws NullArgumentException if the {@code fraction} is {@code null}. 692 * @throws MathArithmeticException if the fraction to divide by is zero 693 */ 694 public BigFraction divide(final BigFraction fraction) { 695 if (fraction == null) { 696 throw new NullArgumentException(LocalizedFormats.FRACTION); 697 } 698 if (fraction.numerator.signum() == 0) { 699 throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); 700 } 701 if (numerator.signum() == 0) { 702 return ZERO; 703 } 704 705 return multiply(fraction.reciprocal()); 706 } 707 708 /** 709 * <p> 710 * Gets the fraction as a {@code double}. This calculates the fraction as 711 * the numerator divided by denominator. 712 * </p> 713 * 714 * @return the fraction as a {@code double} 715 * @see java.lang.Number#doubleValue() 716 */ 717 @Override 718 public double doubleValue() { 719 double result = numerator.doubleValue() / denominator.doubleValue(); 720 if (Double.isNaN(result)) { 721 // Numerator and/or denominator must be out of range: 722 // Calculate how far to shift them to put them in range. 723 int shift = FastMath.max(numerator.bitLength(), 724 denominator.bitLength()) - FastMath.getExponent(Double.MAX_VALUE); 725 result = numerator.shiftRight(shift).doubleValue() / 726 denominator.shiftRight(shift).doubleValue(); 727 } 728 return result; 729 } 730 731 /** 732 * <p> 733 * Test for the equality of two fractions. If the lowest term numerator and 734 * denominators are the same for both fractions, the two fractions are 735 * considered to be equal. 736 * </p> 737 * 738 * @param other 739 * fraction to test for equality to this fraction, can be 740 * <code>null</code>. 741 * @return true if two fractions are equal, false if object is 742 * <code>null</code>, not an instance of {@link BigFraction}, or not 743 * equal to this fraction instance. 744 * @see java.lang.Object#equals(java.lang.Object) 745 */ 746 @Override 747 public boolean equals(final Object other) { 748 boolean ret = false; 749 750 if (this == other) { 751 ret = true; 752 } else if (other instanceof BigFraction) { 753 BigFraction rhs = ((BigFraction) other).reduce(); 754 BigFraction thisOne = this.reduce(); 755 ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator); 756 } 757 758 return ret; 759 } 760 761 /** 762 * <p> 763 * Gets the fraction as a {@code float}. This calculates the fraction as 764 * the numerator divided by denominator. 765 * </p> 766 * 767 * @return the fraction as a {@code float}. 768 * @see java.lang.Number#floatValue() 769 */ 770 @Override 771 public float floatValue() { 772 float result = numerator.floatValue() / denominator.floatValue(); 773 if (Double.isNaN(result)) { 774 // Numerator and/or denominator must be out of range: 775 // Calculate how far to shift them to put them in range. 776 int shift = FastMath.max(numerator.bitLength(), 777 denominator.bitLength()) - FastMath.getExponent(Float.MAX_VALUE); 778 result = numerator.shiftRight(shift).floatValue() / 779 denominator.shiftRight(shift).floatValue(); 780 } 781 return result; 782 } 783 784 /** 785 * <p> 786 * Access the denominator as a <code>BigInteger</code>. 787 * </p> 788 * 789 * @return the denominator as a <code>BigInteger</code>. 790 */ 791 public BigInteger getDenominator() { 792 return denominator; 793 } 794 795 /** 796 * <p> 797 * Access the denominator as a {@code int}. 798 * </p> 799 * 800 * @return the denominator as a {@code int}. 801 */ 802 public int getDenominatorAsInt() { 803 return denominator.intValue(); 804 } 805 806 /** 807 * <p> 808 * Access the denominator as a {@code long}. 809 * </p> 810 * 811 * @return the denominator as a {@code long}. 812 */ 813 public long getDenominatorAsLong() { 814 return denominator.longValue(); 815 } 816 817 /** 818 * <p> 819 * Access the numerator as a <code>BigInteger</code>. 820 * </p> 821 * 822 * @return the numerator as a <code>BigInteger</code>. 823 */ 824 public BigInteger getNumerator() { 825 return numerator; 826 } 827 828 /** 829 * <p> 830 * Access the numerator as a {@code int}. 831 * </p> 832 * 833 * @return the numerator as a {@code int}. 834 */ 835 public int getNumeratorAsInt() { 836 return numerator.intValue(); 837 } 838 839 /** 840 * <p> 841 * Access the numerator as a {@code long}. 842 * </p> 843 * 844 * @return the numerator as a {@code long}. 845 */ 846 public long getNumeratorAsLong() { 847 return numerator.longValue(); 848 } 849 850 /** 851 * <p> 852 * Gets a hashCode for the fraction. 853 * </p> 854 * 855 * @return a hash code value for this object. 856 * @see java.lang.Object#hashCode() 857 */ 858 @Override 859 public int hashCode() { 860 return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode(); 861 } 862 863 /** 864 * <p> 865 * Gets the fraction as an {@code int}. This returns the whole number part 866 * of the fraction. 867 * </p> 868 * 869 * @return the whole number fraction part. 870 * @see java.lang.Number#intValue() 871 */ 872 @Override 873 public int intValue() { 874 return numerator.divide(denominator).intValue(); 875 } 876 877 /** 878 * <p> 879 * Gets the fraction as a {@code long}. This returns the whole number part 880 * of the fraction. 881 * </p> 882 * 883 * @return the whole number fraction part. 884 * @see java.lang.Number#longValue() 885 */ 886 @Override 887 public long longValue() { 888 return numerator.divide(denominator).longValue(); 889 } 890 891 /** 892 * <p> 893 * Multiplies the value of this fraction by the passed 894 * <code>BigInteger</code>, returning the result in reduced form. 895 * </p> 896 * 897 * @param bg the {@code BigInteger} to multiply by. 898 * @return a {@code BigFraction} instance with the resulting values. 899 * @throws NullArgumentException if {@code bg} is {@code null}. 900 */ 901 public BigFraction multiply(final BigInteger bg) { 902 if (bg == null) { 903 throw new NullArgumentException(); 904 } 905 if (numerator.signum() == 0 || bg.signum() == 0) { 906 return ZERO; 907 } 908 return new BigFraction(bg.multiply(numerator), denominator); 909 } 910 911 /** 912 * <p> 913 * Multiply the value of this fraction by the passed {@code int}, returning 914 * the result in reduced form. 915 * </p> 916 * 917 * @param i 918 * the {@code int} to multiply by. 919 * @return a {@link BigFraction} instance with the resulting values. 920 */ 921 public BigFraction multiply(final int i) { 922 if (i == 0 || numerator.signum() == 0) { 923 return ZERO; 924 } 925 926 return multiply(BigInteger.valueOf(i)); 927 } 928 929 /** 930 * <p> 931 * Multiply the value of this fraction by the passed {@code long}, 932 * returning the result in reduced form. 933 * </p> 934 * 935 * @param l 936 * the {@code long} to multiply by. 937 * @return a {@link BigFraction} instance with the resulting values. 938 */ 939 public BigFraction multiply(final long l) { 940 if (l == 0 || numerator.signum() == 0) { 941 return ZERO; 942 } 943 944 return multiply(BigInteger.valueOf(l)); 945 } 946 947 /** 948 * <p> 949 * Multiplies the value of this fraction by another, returning the result in 950 * reduced form. 951 * </p> 952 * 953 * @param fraction Fraction to multiply by, must not be {@code null}. 954 * @return a {@link BigFraction} instance with the resulting values. 955 * @throws NullArgumentException if {@code fraction} is {@code null}. 956 */ 957 public BigFraction multiply(final BigFraction fraction) { 958 if (fraction == null) { 959 throw new NullArgumentException(LocalizedFormats.FRACTION); 960 } 961 if (numerator.signum() == 0 || 962 fraction.numerator.signum() == 0) { 963 return ZERO; 964 } 965 return new BigFraction(numerator.multiply(fraction.numerator), 966 denominator.multiply(fraction.denominator)); 967 } 968 969 /** 970 * <p> 971 * Return the additive inverse of this fraction, returning the result in 972 * reduced form. 973 * </p> 974 * 975 * @return the negation of this fraction. 976 */ 977 public BigFraction negate() { 978 return new BigFraction(numerator.negate(), denominator); 979 } 980 981 /** 982 * <p> 983 * Gets the fraction percentage as a {@code double}. This calculates the 984 * fraction as the numerator divided by denominator multiplied by 100. 985 * </p> 986 * 987 * @return the fraction percentage as a {@code double}. 988 */ 989 public double percentageValue() { 990 return multiply(ONE_HUNDRED).doubleValue(); 991 } 992 993 /** 994 * <p> 995 * Returns a {@code BigFraction} whose value is 996 * {@code (this<sup>exponent</sup>)}, returning the result in reduced form. 997 * </p> 998 * 999 * @param exponent 1000 * exponent to which this {@code BigFraction} is to be 1001 * raised. 1002 * @return <tt>this<sup>exponent</sup></tt>. 1003 */ 1004 public BigFraction pow(final int exponent) { 1005 if (exponent == 0) { 1006 return ONE; 1007 } 1008 if (numerator.signum() == 0) { 1009 return this; 1010 } 1011 1012 if (exponent < 0) { 1013 return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent)); 1014 } 1015 return new BigFraction(numerator.pow(exponent), denominator.pow(exponent)); 1016 } 1017 1018 /** 1019 * <p> 1020 * Returns a <code>BigFraction</code> whose value is 1021 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 1022 * </p> 1023 * 1024 * @param exponent 1025 * exponent to which this <code>BigFraction</code> is to be raised. 1026 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>. 1027 */ 1028 public BigFraction pow(final long exponent) { 1029 if (exponent == 0) { 1030 return ONE; 1031 } 1032 if (numerator.signum() == 0) { 1033 return this; 1034 } 1035 1036 if (exponent < 0) { 1037 return new BigFraction(ArithmeticUtils.pow(denominator, -exponent), 1038 ArithmeticUtils.pow(numerator, -exponent)); 1039 } 1040 return new BigFraction(ArithmeticUtils.pow(numerator, exponent), 1041 ArithmeticUtils.pow(denominator, exponent)); 1042 } 1043 1044 /** 1045 * <p> 1046 * Returns a <code>BigFraction</code> whose value is 1047 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 1048 * </p> 1049 * 1050 * @param exponent 1051 * exponent to which this <code>BigFraction</code> is to be raised. 1052 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>. 1053 */ 1054 public BigFraction pow(final BigInteger exponent) { 1055 if (exponent.signum() == 0) { 1056 return ONE; 1057 } 1058 if (numerator.signum() == 0) { 1059 return this; 1060 } 1061 1062 if (exponent.signum() == -1) { 1063 final BigInteger eNeg = exponent.negate(); 1064 return new BigFraction(ArithmeticUtils.pow(denominator, eNeg), 1065 ArithmeticUtils.pow(numerator, eNeg)); 1066 } 1067 return new BigFraction(ArithmeticUtils.pow(numerator, exponent), 1068 ArithmeticUtils.pow(denominator, exponent)); 1069 } 1070 1071 /** 1072 * <p> 1073 * Returns a <code>double</code> whose value is 1074 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 1075 * </p> 1076 * 1077 * @param exponent 1078 * exponent to which this <code>BigFraction</code> is to be raised. 1079 * @return <tt>this<sup>exponent</sup></tt>. 1080 */ 1081 public double pow(final double exponent) { 1082 return FastMath.pow(numerator.doubleValue(), exponent) / 1083 FastMath.pow(denominator.doubleValue(), exponent); 1084 } 1085 1086 /** 1087 * <p> 1088 * Return the multiplicative inverse of this fraction. 1089 * </p> 1090 * 1091 * @return the reciprocal fraction. 1092 */ 1093 public BigFraction reciprocal() { 1094 return new BigFraction(denominator, numerator); 1095 } 1096 1097 /** 1098 * <p> 1099 * Reduce this <code>BigFraction</code> to its lowest terms. 1100 * </p> 1101 * 1102 * @return the reduced <code>BigFraction</code>. It doesn't change anything if 1103 * the fraction can be reduced. 1104 */ 1105 public BigFraction reduce() { 1106 final BigInteger gcd = numerator.gcd(denominator); 1107 1108 if (BigInteger.ONE.compareTo(gcd) < 0) { 1109 return new BigFraction(numerator.divide(gcd), denominator.divide(gcd)); 1110 } else { 1111 return this; 1112 } 1113 } 1114 1115 /** 1116 * <p> 1117 * Subtracts the value of an {@link BigInteger} from the value of this 1118 * {@code BigFraction}, returning the result in reduced form. 1119 * </p> 1120 * 1121 * @param bg the {@link BigInteger} to subtract, cannot be {@code null}. 1122 * @return a {@code BigFraction} instance with the resulting values. 1123 * @throws NullArgumentException if the {@link BigInteger} is {@code null}. 1124 */ 1125 public BigFraction subtract(final BigInteger bg) { 1126 if (bg == null) { 1127 throw new NullArgumentException(); 1128 } 1129 if (bg.signum() == 0) { 1130 return this; 1131 } 1132 if (numerator.signum() == 0) { 1133 return new BigFraction(bg.negate()); 1134 } 1135 1136 return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator); 1137 } 1138 1139 /** 1140 * <p> 1141 * Subtracts the value of an {@code integer} from the value of this 1142 * {@code BigFraction}, returning the result in reduced form. 1143 * </p> 1144 * 1145 * @param i the {@code integer} to subtract. 1146 * @return a {@code BigFraction} instance with the resulting values. 1147 */ 1148 public BigFraction subtract(final int i) { 1149 return subtract(BigInteger.valueOf(i)); 1150 } 1151 1152 /** 1153 * <p> 1154 * Subtracts the value of a {@code long} from the value of this 1155 * {@code BigFraction}, returning the result in reduced form. 1156 * </p> 1157 * 1158 * @param l the {@code long} to subtract. 1159 * @return a {@code BigFraction} instance with the resulting values. 1160 */ 1161 public BigFraction subtract(final long l) { 1162 return subtract(BigInteger.valueOf(l)); 1163 } 1164 1165 /** 1166 * <p> 1167 * Subtracts the value of another fraction from the value of this one, 1168 * returning the result in reduced form. 1169 * </p> 1170 * 1171 * @param fraction {@link BigFraction} to subtract, must not be {@code null}. 1172 * @return a {@link BigFraction} instance with the resulting values 1173 * @throws NullArgumentException if the {@code fraction} is {@code null}. 1174 */ 1175 public BigFraction subtract(final BigFraction fraction) { 1176 if (fraction == null) { 1177 throw new NullArgumentException(LocalizedFormats.FRACTION); 1178 } 1179 if (fraction.numerator.signum() == 0) { 1180 return this; 1181 } 1182 if (numerator.signum() == 0) { 1183 return fraction.negate(); 1184 } 1185 1186 BigInteger num = null; 1187 BigInteger den = null; 1188 if (denominator.equals(fraction.denominator)) { 1189 num = numerator.subtract(fraction.numerator); 1190 den = denominator; 1191 } else { 1192 num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator)); 1193 den = denominator.multiply(fraction.denominator); 1194 } 1195 return new BigFraction(num, den); 1196 1197 } 1198 1199 /** 1200 * <p> 1201 * Returns the <code>String</code> representing this fraction, ie 1202 * "num / dem" or just "num" if the denominator is one. 1203 * </p> 1204 * 1205 * @return a string representation of the fraction. 1206 * @see java.lang.Object#toString() 1207 */ 1208 @Override 1209 public String toString() { 1210 String str = null; 1211 if (BigInteger.ONE.equals(denominator)) { 1212 str = numerator.toString(); 1213 } else if (BigInteger.ZERO.equals(numerator)) { 1214 str = "0"; 1215 } else { 1216 str = numerator + " / " + denominator; 1217 } 1218 return str; 1219 } 1220 1221 /** {@inheritDoc} */ 1222 public BigFractionField getField() { 1223 return BigFractionField.getInstance(); 1224 } 1225 1226}