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