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 (BigInteger.ZERO.equals(den)) { 123 throw new ZeroException(LocalizedFormats.ZERO_DENOMINATOR); 124 } 125 if (BigInteger.ZERO.equals(num)) { 126 numerator = BigInteger.ZERO; 127 denominator = BigInteger.ONE; 128 } else { 129 130 // reduce numerator and denominator by greatest common denominator 131 final BigInteger gcd = num.gcd(den); 132 if (BigInteger.ONE.compareTo(gcd) < 0) { 133 num = num.divide(gcd); 134 den = den.divide(gcd); 135 } 136 137 // move sign to numerator 138 if (BigInteger.ZERO.compareTo(den) > 0) { 139 num = num.negate(); 140 den = den.negate(); 141 } 142 143 // store the values in the final fields 144 numerator = num; 145 denominator = den; 146 147 } 148 } 149 150 /** 151 * Create a fraction given the double value. 152 * <p> 153 * This constructor behaves <em>differently</em> from 154 * {@link #BigFraction(double, double, int)}. It converts the 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 (BigInteger.ZERO.compareTo(numerator) <= 0) ? 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 return new BigFraction(numerator.add(denominator.multiply(bg)), denominator); 471 } 472 473 /** 474 * <p> 475 * Adds the value of this fraction to the passed {@code integer}, returning 476 * the result in reduced form. 477 * </p> 478 * 479 * @param i 480 * the {@code integer} to add. 481 * @return a <code>BigFraction</code> instance with the resulting values. 482 */ 483 public BigFraction add(final int i) { 484 return add(BigInteger.valueOf(i)); 485 } 486 487 /** 488 * <p> 489 * Adds the value of this fraction to the passed {@code long}, returning 490 * the result in reduced form. 491 * </p> 492 * 493 * @param l 494 * the {@code long} to add. 495 * @return a <code>BigFraction</code> instance with the resulting values. 496 */ 497 public BigFraction add(final long l) { 498 return add(BigInteger.valueOf(l)); 499 } 500 501 /** 502 * <p> 503 * Adds the value of this fraction to another, returning the result in 504 * reduced form. 505 * </p> 506 * 507 * @param fraction 508 * the {@link BigFraction} to add, must not be <code>null</code>. 509 * @return a {@link BigFraction} instance with the resulting values. 510 * @throws NullArgumentException if the {@link BigFraction} is {@code null}. 511 */ 512 public BigFraction add(final BigFraction fraction) { 513 if (fraction == null) { 514 throw new NullArgumentException(LocalizedFormats.FRACTION); 515 } 516 if (ZERO.equals(fraction)) { 517 return this; 518 } 519 520 BigInteger num = null; 521 BigInteger den = null; 522 523 if (denominator.equals(fraction.denominator)) { 524 num = numerator.add(fraction.numerator); 525 den = denominator; 526 } else { 527 num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator)); 528 den = denominator.multiply(fraction.denominator); 529 } 530 return new BigFraction(num, den); 531 532 } 533 534 /** 535 * <p> 536 * Gets the fraction as a <code>BigDecimal</code>. This calculates the 537 * fraction as the numerator divided by denominator. 538 * </p> 539 * 540 * @return the fraction as a <code>BigDecimal</code>. 541 * @throws ArithmeticException 542 * if the exact quotient does not have a terminating decimal 543 * expansion. 544 * @see BigDecimal 545 */ 546 public BigDecimal bigDecimalValue() { 547 return new BigDecimal(numerator).divide(new BigDecimal(denominator)); 548 } 549 550 /** 551 * <p> 552 * Gets the fraction as a <code>BigDecimal</code> following the passed 553 * rounding mode. This calculates the fraction as the numerator divided by 554 * denominator. 555 * </p> 556 * 557 * @param roundingMode 558 * rounding mode to apply. see {@link BigDecimal} constants. 559 * @return the fraction as a <code>BigDecimal</code>. 560 * @throws IllegalArgumentException 561 * if {@code roundingMode} does not represent a valid rounding 562 * mode. 563 * @see BigDecimal 564 */ 565 public BigDecimal bigDecimalValue(final int roundingMode) { 566 return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode); 567 } 568 569 /** 570 * <p> 571 * Gets the fraction as a <code>BigDecimal</code> following the passed scale 572 * and rounding mode. This calculates the fraction as the numerator divided 573 * by denominator. 574 * </p> 575 * 576 * @param scale 577 * scale of the <code>BigDecimal</code> quotient to be returned. 578 * see {@link BigDecimal} for more information. 579 * @param roundingMode 580 * rounding mode to apply. see {@link BigDecimal} constants. 581 * @return the fraction as a <code>BigDecimal</code>. 582 * @see BigDecimal 583 */ 584 public BigDecimal bigDecimalValue(final int scale, final int roundingMode) { 585 return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode); 586 } 587 588 /** 589 * <p> 590 * Compares this object to another based on size. 591 * </p> 592 * 593 * @param object 594 * the object to compare to, must not be <code>null</code>. 595 * @return -1 if this is less than {@code object}, +1 if this is greater 596 * than {@code object}, 0 if they are equal. 597 * @see java.lang.Comparable#compareTo(java.lang.Object) 598 */ 599 public int compareTo(final BigFraction object) { 600 BigInteger nOd = numerator.multiply(object.denominator); 601 BigInteger dOn = denominator.multiply(object.numerator); 602 return nOd.compareTo(dOn); 603 } 604 605 /** 606 * <p> 607 * Divide the value of this fraction by the passed {@code BigInteger}, 608 * ie {@code this * 1 / bg}, returning the result in reduced form. 609 * </p> 610 * 611 * @param bg the {@code BigInteger} to divide by, must not be {@code null} 612 * @return a {@link BigFraction} instance with the resulting values 613 * @throws NullArgumentException if the {@code BigInteger} is {@code null} 614 * @throws MathArithmeticException if the fraction to divide by is zero 615 */ 616 public BigFraction divide(final BigInteger bg) { 617 if (bg == null) { 618 throw new NullArgumentException(LocalizedFormats.FRACTION); 619 } 620 if (BigInteger.ZERO.equals(bg)) { 621 throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); 622 } 623 return new BigFraction(numerator, denominator.multiply(bg)); 624 } 625 626 /** 627 * <p> 628 * Divide the value of this fraction by the passed {@code int}, ie 629 * {@code this * 1 / i}, returning the result in reduced form. 630 * </p> 631 * 632 * @param i the {@code int} to divide by 633 * @return a {@link BigFraction} instance with the resulting values 634 * @throws MathArithmeticException if the fraction to divide by is zero 635 */ 636 public BigFraction divide(final int i) { 637 return divide(BigInteger.valueOf(i)); 638 } 639 640 /** 641 * <p> 642 * Divide the value of this fraction by the passed {@code long}, ie 643 * {@code this * 1 / l}, returning the result in reduced form. 644 * </p> 645 * 646 * @param l the {@code long} to divide by 647 * @return a {@link BigFraction} instance with the resulting values 648 * @throws MathArithmeticException if the fraction to divide by is zero 649 */ 650 public BigFraction divide(final long l) { 651 return divide(BigInteger.valueOf(l)); 652 } 653 654 /** 655 * <p> 656 * Divide the value of this fraction by another, returning the result in 657 * reduced form. 658 * </p> 659 * 660 * @param fraction Fraction to divide by, must not be {@code null}. 661 * @return a {@link BigFraction} instance with the resulting values. 662 * @throws NullArgumentException if the {@code fraction} is {@code null}. 663 * @throws MathArithmeticException if the fraction to divide by is zero 664 */ 665 public BigFraction divide(final BigFraction fraction) { 666 if (fraction == null) { 667 throw new NullArgumentException(LocalizedFormats.FRACTION); 668 } 669 if (BigInteger.ZERO.equals(fraction.numerator)) { 670 throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); 671 } 672 673 return multiply(fraction.reciprocal()); 674 } 675 676 /** 677 * <p> 678 * Gets the fraction as a {@code double}. This calculates the fraction as 679 * the numerator divided by denominator. 680 * </p> 681 * 682 * @return the fraction as a {@code double} 683 * @see java.lang.Number#doubleValue() 684 */ 685 @Override 686 public double doubleValue() { 687 double result = numerator.doubleValue() / denominator.doubleValue(); 688 if (Double.isNaN(result)) { 689 // Numerator and/or denominator must be out of range: 690 // Calculate how far to shift them to put them in range. 691 int shift = FastMath.max(numerator.bitLength(), 692 denominator.bitLength()) - FastMath.getExponent(Double.MAX_VALUE); 693 result = numerator.shiftRight(shift).doubleValue() / 694 denominator.shiftRight(shift).doubleValue(); 695 } 696 return result; 697 } 698 699 /** 700 * <p> 701 * Test for the equality of two fractions. If the lowest term numerator and 702 * denominators are the same for both fractions, the two fractions are 703 * considered to be equal. 704 * </p> 705 * 706 * @param other 707 * fraction to test for equality to this fraction, can be 708 * <code>null</code>. 709 * @return true if two fractions are equal, false if object is 710 * <code>null</code>, not an instance of {@link BigFraction}, or not 711 * equal to this fraction instance. 712 * @see java.lang.Object#equals(java.lang.Object) 713 */ 714 @Override 715 public boolean equals(final Object other) { 716 boolean ret = false; 717 718 if (this == other) { 719 ret = true; 720 } else if (other instanceof BigFraction) { 721 BigFraction rhs = ((BigFraction) other).reduce(); 722 BigFraction thisOne = this.reduce(); 723 ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator); 724 } 725 726 return ret; 727 } 728 729 /** 730 * <p> 731 * Gets the fraction as a {@code float}. This calculates the fraction as 732 * the numerator divided by denominator. 733 * </p> 734 * 735 * @return the fraction as a {@code float}. 736 * @see java.lang.Number#floatValue() 737 */ 738 @Override 739 public float floatValue() { 740 float result = numerator.floatValue() / denominator.floatValue(); 741 if (Double.isNaN(result)) { 742 // Numerator and/or denominator must be out of range: 743 // Calculate how far to shift them to put them in range. 744 int shift = FastMath.max(numerator.bitLength(), 745 denominator.bitLength()) - FastMath.getExponent(Float.MAX_VALUE); 746 result = numerator.shiftRight(shift).floatValue() / 747 denominator.shiftRight(shift).floatValue(); 748 } 749 return result; 750 } 751 752 /** 753 * <p> 754 * Access the denominator as a <code>BigInteger</code>. 755 * </p> 756 * 757 * @return the denominator as a <code>BigInteger</code>. 758 */ 759 public BigInteger getDenominator() { 760 return denominator; 761 } 762 763 /** 764 * <p> 765 * Access the denominator as a {@code int}. 766 * </p> 767 * 768 * @return the denominator as a {@code int}. 769 */ 770 public int getDenominatorAsInt() { 771 return denominator.intValue(); 772 } 773 774 /** 775 * <p> 776 * Access the denominator as a {@code long}. 777 * </p> 778 * 779 * @return the denominator as a {@code long}. 780 */ 781 public long getDenominatorAsLong() { 782 return denominator.longValue(); 783 } 784 785 /** 786 * <p> 787 * Access the numerator as a <code>BigInteger</code>. 788 * </p> 789 * 790 * @return the numerator as a <code>BigInteger</code>. 791 */ 792 public BigInteger getNumerator() { 793 return numerator; 794 } 795 796 /** 797 * <p> 798 * Access the numerator as a {@code int}. 799 * </p> 800 * 801 * @return the numerator as a {@code int}. 802 */ 803 public int getNumeratorAsInt() { 804 return numerator.intValue(); 805 } 806 807 /** 808 * <p> 809 * Access the numerator as a {@code long}. 810 * </p> 811 * 812 * @return the numerator as a {@code long}. 813 */ 814 public long getNumeratorAsLong() { 815 return numerator.longValue(); 816 } 817 818 /** 819 * <p> 820 * Gets a hashCode for the fraction. 821 * </p> 822 * 823 * @return a hash code value for this object. 824 * @see java.lang.Object#hashCode() 825 */ 826 @Override 827 public int hashCode() { 828 return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode(); 829 } 830 831 /** 832 * <p> 833 * Gets the fraction as an {@code int}. This returns the whole number part 834 * of the fraction. 835 * </p> 836 * 837 * @return the whole number fraction part. 838 * @see java.lang.Number#intValue() 839 */ 840 @Override 841 public int intValue() { 842 return numerator.divide(denominator).intValue(); 843 } 844 845 /** 846 * <p> 847 * Gets the fraction as a {@code long}. This returns the whole number part 848 * of the fraction. 849 * </p> 850 * 851 * @return the whole number fraction part. 852 * @see java.lang.Number#longValue() 853 */ 854 @Override 855 public long longValue() { 856 return numerator.divide(denominator).longValue(); 857 } 858 859 /** 860 * <p> 861 * Multiplies the value of this fraction by the passed 862 * <code>BigInteger</code>, returning the result in reduced form. 863 * </p> 864 * 865 * @param bg the {@code BigInteger} to multiply by. 866 * @return a {@code BigFraction} instance with the resulting values. 867 * @throws NullArgumentException if {@code bg} is {@code null}. 868 */ 869 public BigFraction multiply(final BigInteger bg) { 870 if (bg == null) { 871 throw new NullArgumentException(); 872 } 873 return new BigFraction(bg.multiply(numerator), denominator); 874 } 875 876 /** 877 * <p> 878 * Multiply the value of this fraction by the passed {@code int}, returning 879 * the result in reduced form. 880 * </p> 881 * 882 * @param i 883 * the {@code int} to multiply by. 884 * @return a {@link BigFraction} instance with the resulting values. 885 */ 886 public BigFraction multiply(final int i) { 887 return multiply(BigInteger.valueOf(i)); 888 } 889 890 /** 891 * <p> 892 * Multiply the value of this fraction by the passed {@code long}, 893 * returning the result in reduced form. 894 * </p> 895 * 896 * @param l 897 * the {@code long} to multiply by. 898 * @return a {@link BigFraction} instance with the resulting values. 899 */ 900 public BigFraction multiply(final long l) { 901 return multiply(BigInteger.valueOf(l)); 902 } 903 904 /** 905 * <p> 906 * Multiplies the value of this fraction by another, returning the result in 907 * reduced form. 908 * </p> 909 * 910 * @param fraction Fraction to multiply by, must not be {@code null}. 911 * @return a {@link BigFraction} instance with the resulting values. 912 * @throws NullArgumentException if {@code fraction} is {@code null}. 913 */ 914 public BigFraction multiply(final BigFraction fraction) { 915 if (fraction == null) { 916 throw new NullArgumentException(LocalizedFormats.FRACTION); 917 } 918 if (numerator.equals(BigInteger.ZERO) || 919 fraction.numerator.equals(BigInteger.ZERO)) { 920 return ZERO; 921 } 922 return new BigFraction(numerator.multiply(fraction.numerator), 923 denominator.multiply(fraction.denominator)); 924 } 925 926 /** 927 * <p> 928 * Return the additive inverse of this fraction, returning the result in 929 * reduced form. 930 * </p> 931 * 932 * @return the negation of this fraction. 933 */ 934 public BigFraction negate() { 935 return new BigFraction(numerator.negate(), denominator); 936 } 937 938 /** 939 * <p> 940 * Gets the fraction percentage as a {@code double}. This calculates the 941 * fraction as the numerator divided by denominator multiplied by 100. 942 * </p> 943 * 944 * @return the fraction percentage as a {@code double}. 945 */ 946 public double percentageValue() { 947 return multiply(ONE_HUNDRED).doubleValue(); 948 } 949 950 /** 951 * <p> 952 * Returns a {@code BigFraction} whose value is 953 * {@code (this<sup>exponent</sup>)}, returning the result in reduced form. 954 * </p> 955 * 956 * @param exponent 957 * exponent to which this {@code BigFraction} is to be 958 * raised. 959 * @return <tt>this<sup>exponent</sup></tt>. 960 */ 961 public BigFraction pow(final int exponent) { 962 if (exponent < 0) { 963 return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent)); 964 } 965 return new BigFraction(numerator.pow(exponent), denominator.pow(exponent)); 966 } 967 968 /** 969 * <p> 970 * Returns a <code>BigFraction</code> whose value is 971 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 972 * </p> 973 * 974 * @param exponent 975 * exponent to which this <code>BigFraction</code> is to be raised. 976 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>. 977 */ 978 public BigFraction pow(final long exponent) { 979 if (exponent < 0) { 980 return new BigFraction(ArithmeticUtils.pow(denominator, -exponent), 981 ArithmeticUtils.pow(numerator, -exponent)); 982 } 983 return new BigFraction(ArithmeticUtils.pow(numerator, exponent), 984 ArithmeticUtils.pow(denominator, exponent)); 985 } 986 987 /** 988 * <p> 989 * Returns a <code>BigFraction</code> whose value is 990 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 991 * </p> 992 * 993 * @param exponent 994 * exponent to which this <code>BigFraction</code> is to be raised. 995 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>. 996 */ 997 public BigFraction pow(final BigInteger exponent) { 998 if (exponent.compareTo(BigInteger.ZERO) < 0) { 999 final BigInteger eNeg = exponent.negate(); 1000 return new BigFraction(ArithmeticUtils.pow(denominator, eNeg), 1001 ArithmeticUtils.pow(numerator, eNeg)); 1002 } 1003 return new BigFraction(ArithmeticUtils.pow(numerator, exponent), 1004 ArithmeticUtils.pow(denominator, exponent)); 1005 } 1006 1007 /** 1008 * <p> 1009 * Returns a <code>double</code> whose value is 1010 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 1011 * </p> 1012 * 1013 * @param exponent 1014 * exponent to which this <code>BigFraction</code> is to be raised. 1015 * @return <tt>this<sup>exponent</sup></tt>. 1016 */ 1017 public double pow(final double exponent) { 1018 return FastMath.pow(numerator.doubleValue(), exponent) / 1019 FastMath.pow(denominator.doubleValue(), exponent); 1020 } 1021 1022 /** 1023 * <p> 1024 * Return the multiplicative inverse of this fraction. 1025 * </p> 1026 * 1027 * @return the reciprocal fraction. 1028 */ 1029 public BigFraction reciprocal() { 1030 return new BigFraction(denominator, numerator); 1031 } 1032 1033 /** 1034 * <p> 1035 * Reduce this <code>BigFraction</code> to its lowest terms. 1036 * </p> 1037 * 1038 * @return the reduced <code>BigFraction</code>. It doesn't change anything if 1039 * the fraction can be reduced. 1040 */ 1041 public BigFraction reduce() { 1042 final BigInteger gcd = numerator.gcd(denominator); 1043 return new BigFraction(numerator.divide(gcd), denominator.divide(gcd)); 1044 } 1045 1046 /** 1047 * <p> 1048 * Subtracts the value of an {@link BigInteger} from the value of this 1049 * {@code BigFraction}, returning the result in reduced form. 1050 * </p> 1051 * 1052 * @param bg the {@link BigInteger} to subtract, cannot be {@code null}. 1053 * @return a {@code BigFraction} instance with the resulting values. 1054 * @throws NullArgumentException if the {@link BigInteger} is {@code null}. 1055 */ 1056 public BigFraction subtract(final BigInteger bg) { 1057 if (bg == null) { 1058 throw new NullArgumentException(); 1059 } 1060 return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator); 1061 } 1062 1063 /** 1064 * <p> 1065 * Subtracts the value of an {@code integer} from the value of this 1066 * {@code BigFraction}, returning the result in reduced form. 1067 * </p> 1068 * 1069 * @param i the {@code integer} to subtract. 1070 * @return a {@code BigFraction} instance with the resulting values. 1071 */ 1072 public BigFraction subtract(final int i) { 1073 return subtract(BigInteger.valueOf(i)); 1074 } 1075 1076 /** 1077 * <p> 1078 * Subtracts the value of a {@code long} from the value of this 1079 * {@code BigFraction}, returning the result in reduced form. 1080 * </p> 1081 * 1082 * @param l the {@code long} to subtract. 1083 * @return a {@code BigFraction} instance with the resulting values. 1084 */ 1085 public BigFraction subtract(final long l) { 1086 return subtract(BigInteger.valueOf(l)); 1087 } 1088 1089 /** 1090 * <p> 1091 * Subtracts the value of another fraction from the value of this one, 1092 * returning the result in reduced form. 1093 * </p> 1094 * 1095 * @param fraction {@link BigFraction} to subtract, must not be {@code null}. 1096 * @return a {@link BigFraction} instance with the resulting values 1097 * @throws NullArgumentException if the {@code fraction} is {@code null}. 1098 */ 1099 public BigFraction subtract(final BigFraction fraction) { 1100 if (fraction == null) { 1101 throw new NullArgumentException(LocalizedFormats.FRACTION); 1102 } 1103 if (ZERO.equals(fraction)) { 1104 return this; 1105 } 1106 1107 BigInteger num = null; 1108 BigInteger den = null; 1109 if (denominator.equals(fraction.denominator)) { 1110 num = numerator.subtract(fraction.numerator); 1111 den = denominator; 1112 } else { 1113 num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator)); 1114 den = denominator.multiply(fraction.denominator); 1115 } 1116 return new BigFraction(num, den); 1117 1118 } 1119 1120 /** 1121 * <p> 1122 * Returns the <code>String</code> representing this fraction, ie 1123 * "num / dem" or just "num" if the denominator is one. 1124 * </p> 1125 * 1126 * @return a string representation of the fraction. 1127 * @see java.lang.Object#toString() 1128 */ 1129 @Override 1130 public String toString() { 1131 String str = null; 1132 if (BigInteger.ONE.equals(denominator)) { 1133 str = numerator.toString(); 1134 } else if (BigInteger.ZERO.equals(numerator)) { 1135 str = "0"; 1136 } else { 1137 str = numerator + " / " + denominator; 1138 } 1139 return str; 1140 } 1141 1142 /** {@inheritDoc} */ 1143 public BigFractionField getField() { 1144 return BigFractionField.getInstance(); 1145 } 1146 1147}