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 */ 017 package org.apache.commons.math.fraction; 018 019 import java.io.Serializable; 020 import java.math.BigDecimal; 021 import java.math.BigInteger; 022 023 import org.apache.commons.math.FieldElement; 024 import org.apache.commons.math.MathRuntimeException; 025 import org.apache.commons.math.util.MathUtils; 026 027 /** 028 * Representation of a rational number without any overflow. This class is 029 * immutable. 030 * 031 * @version $Revision: 906251 $ $Date: 2010-02-03 16:19:54 -0500 (Wed, 03 Feb 2010) $ 032 * @since 2.0 033 */ 034 public class BigFraction 035 extends Number 036 implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable { 037 038 /** A fraction representing "2 / 1". */ 039 public static final BigFraction TWO = new BigFraction(2); 040 041 /** A fraction representing "1". */ 042 public static final BigFraction ONE = new BigFraction(1); 043 044 /** A fraction representing "0". */ 045 public static final BigFraction ZERO = new BigFraction(0); 046 047 /** A fraction representing "-1 / 1". */ 048 public static final BigFraction MINUS_ONE = new BigFraction(-1); 049 050 /** A fraction representing "4/5". */ 051 public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5); 052 053 /** A fraction representing "1/5". */ 054 public static final BigFraction ONE_FIFTH = new BigFraction(1, 5); 055 056 /** A fraction representing "1/2". */ 057 public static final BigFraction ONE_HALF = new BigFraction(1, 2); 058 059 /** A fraction representing "1/4". */ 060 public static final BigFraction ONE_QUARTER = new BigFraction(1, 4); 061 062 /** A fraction representing "1/3". */ 063 public static final BigFraction ONE_THIRD = new BigFraction(1, 3); 064 065 /** A fraction representing "3/5". */ 066 public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5); 067 068 /** A fraction representing "3/4". */ 069 public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4); 070 071 /** A fraction representing "2/5". */ 072 public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5); 073 074 /** A fraction representing "2/4". */ 075 public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4); 076 077 /** A fraction representing "2/3". */ 078 public static final BigFraction TWO_THIRDS = new BigFraction(2, 3); 079 080 /** Serializable version identifier. */ 081 private static final long serialVersionUID = -5630213147331578515L; 082 083 /** Message for zero denominator. */ 084 private static final String FORBIDDEN_ZERO_DENOMINATOR = 085 "denominator must be different from 0"; 086 087 /** <code>BigInteger</code> representation of 100. */ 088 private static final BigInteger ONE_HUNDRED_DOUBLE = BigInteger.valueOf(100); 089 090 /** The numerator. */ 091 private final BigInteger numerator; 092 093 /** The denominator. */ 094 private final BigInteger denominator; 095 096 /** 097 * <p> 098 * Create a {@link BigFraction} equivalent to the passed <tt>BigInteger</tt>, ie 099 * "num / 1". 100 * </p> 101 * 102 * @param num 103 * the numerator. 104 */ 105 public BigFraction(final BigInteger num) { 106 this(num, BigInteger.ONE); 107 } 108 109 /** 110 * <p> 111 * Create a {@link BigFraction} given the numerator and denominator as 112 * <code>BigInteger</code>. The {@link BigFraction} is reduced to lowest terms. 113 * </p> 114 * 115 * @param num 116 * the numerator, must not be <code>null</code>. 117 * @param den 118 * the denominator, must not be <code>null</code>. 119 * @throws ArithmeticException 120 * if the denominator is <code>zero</code>. 121 * @throws NullPointerException 122 * if the numerator or the denominator is <code>zero</code>. 123 */ 124 public BigFraction(BigInteger num, BigInteger den) { 125 if (num == null) { 126 throw MathRuntimeException.createNullPointerException("numerator is null"); 127 } 128 if (den == null) { 129 throw MathRuntimeException.createNullPointerException("denominator is null"); 130 } 131 if (BigInteger.ZERO.equals(den)) { 132 throw MathRuntimeException.createArithmeticException(FORBIDDEN_ZERO_DENOMINATOR); 133 } 134 if (BigInteger.ZERO.equals(num)) { 135 numerator = BigInteger.ZERO; 136 denominator = BigInteger.ONE; 137 } else { 138 139 // reduce numerator and denominator by greatest common denominator 140 final BigInteger gcd = num.gcd(den); 141 if (BigInteger.ONE.compareTo(gcd) < 0) { 142 num = num.divide(gcd); 143 den = den.divide(gcd); 144 } 145 146 // move sign to numerator 147 if (BigInteger.ZERO.compareTo(den) > 0) { 148 num = num.negate(); 149 den = den.negate(); 150 } 151 152 // store the values in the final fields 153 numerator = num; 154 denominator = den; 155 156 } 157 } 158 159 /** 160 * Create a fraction given the double value. 161 * <p> 162 * This constructor behaves <em>differently</em> from 163 * {@link #BigFraction(double, double, int)}. It converts the 164 * double value exactly, considering its internal bits representation. 165 * This does work for all values except NaN and infinities and does 166 * not requires any loop or convergence threshold. 167 * </p> 168 * <p> 169 * Since this conversion is exact and since double numbers are sometimes 170 * approximated, the fraction created may seem strange in some cases. For example 171 * calling <code>new BigFraction(1.0 / 3.0)</code> does <em>not</em> create 172 * the fraction 1/3 but the fraction 6004799503160661 / 18014398509481984 173 * because the double number passed to the constructor is not exactly 1/3 174 * (this number cannot be stored exactly in IEEE754). 175 * </p> 176 * @see #BigFraction(double, double, int) 177 * @param value the double value to convert to a fraction. 178 * @exception IllegalArgumentException if value is NaN or infinite 179 */ 180 public BigFraction(final double value) throws IllegalArgumentException { 181 if (Double.isNaN(value)) { 182 throw MathRuntimeException.createIllegalArgumentException("cannot convert NaN value"); 183 } 184 if (Double.isInfinite(value)) { 185 throw MathRuntimeException.createIllegalArgumentException("cannot convert infinite value"); 186 } 187 188 // compute m and k such that value = m * 2^k 189 final long bits = Double.doubleToLongBits(value); 190 final long sign = bits & 0x8000000000000000L; 191 final long exponent = bits & 0x7ff0000000000000L; 192 long m = bits & 0x000fffffffffffffL; 193 if (exponent != 0) { 194 // this was a normalized number, add the implicit most significant bit 195 m |= 0x0010000000000000L; 196 } 197 if (sign != 0) { 198 m = -m; 199 } 200 int k = ((int) (exponent >> 52)) - 1075; 201 while (((m & 0x001ffffffffffffeL) != 0) && ((m & 0x1) == 0)) { 202 m = m >> 1; 203 ++k; 204 } 205 206 if (k < 0) { 207 numerator = BigInteger.valueOf(m); 208 denominator = BigInteger.ZERO.flipBit(-k); 209 } else { 210 numerator = BigInteger.valueOf(m).multiply(BigInteger.ZERO.flipBit(k)); 211 denominator = BigInteger.ONE; 212 } 213 214 } 215 216 /** 217 * Create a fraction given the double value and maximum error allowed. 218 * <p> 219 * References: 220 * <ul> 221 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> 222 * Continued Fraction</a> equations (11) and (22)-(26)</li> 223 * </ul> 224 * </p> 225 * 226 * @param value 227 * the double value to convert to a fraction. 228 * @param epsilon 229 * maximum error allowed. The resulting fraction is within 230 * <code>epsilon</code> of <code>value</code>, in absolute terms. 231 * @param maxIterations 232 * maximum number of convergents. 233 * @throws FractionConversionException 234 * if the continued fraction failed to converge. 235 * @see #BigFraction(double) 236 */ 237 public BigFraction(final double value, final double epsilon, 238 final int maxIterations) 239 throws FractionConversionException { 240 this(value, epsilon, Integer.MAX_VALUE, maxIterations); 241 } 242 243 /** 244 * Create a fraction given the double value and either the maximum error 245 * allowed or the maximum number of denominator digits. 246 * <p> 247 * 248 * NOTE: This constructor is called with EITHER - a valid epsilon value and 249 * the maxDenominator set to Integer.MAX_VALUE (that way the maxDenominator 250 * has no effect). OR - a valid maxDenominator value and the epsilon value 251 * set to zero (that way epsilon only has effect if there is an exact match 252 * before the maxDenominator value is reached). 253 * </p> 254 * <p> 255 * 256 * It has been done this way so that the same code can be (re)used for both 257 * scenarios. However this could be confusing to users if it were part of 258 * the public API and this constructor should therefore remain PRIVATE. 259 * </p> 260 * 261 * See JIRA issue ticket MATH-181 for more details: 262 * 263 * https://issues.apache.org/jira/browse/MATH-181 264 * 265 * @param value 266 * the double value to convert to a fraction. 267 * @param epsilon 268 * maximum error allowed. The resulting fraction is within 269 * <code>epsilon</code> of <code>value</code>, in absolute terms. 270 * @param maxDenominator 271 * maximum denominator value allowed. 272 * @param maxIterations 273 * maximum number of convergents. 274 * @throws FractionConversionException 275 * if the continued fraction failed to converge. 276 */ 277 private BigFraction(final double value, final double epsilon, 278 final int maxDenominator, int maxIterations) 279 throws FractionConversionException { 280 long overflow = Integer.MAX_VALUE; 281 double r0 = value; 282 long a0 = (long) Math.floor(r0); 283 if (a0 > overflow) { 284 throw new FractionConversionException(value, a0, 1l); 285 } 286 287 // check for (almost) integer arguments, which should not go 288 // to iterations. 289 if (Math.abs(a0 - value) < epsilon) { 290 numerator = BigInteger.valueOf(a0); 291 denominator = BigInteger.ONE; 292 return; 293 } 294 295 long p0 = 1; 296 long q0 = 0; 297 long p1 = a0; 298 long q1 = 1; 299 300 long p2 = 0; 301 long q2 = 1; 302 303 int n = 0; 304 boolean stop = false; 305 do { 306 ++n; 307 final double r1 = 1.0 / (r0 - a0); 308 final long a1 = (long) Math.floor(r1); 309 p2 = (a1 * p1) + p0; 310 q2 = (a1 * q1) + q0; 311 if ((p2 > overflow) || (q2 > overflow)) { 312 throw new FractionConversionException(value, p2, q2); 313 } 314 315 final double convergent = (double) p2 / (double) q2; 316 if ((n < maxIterations) && 317 (Math.abs(convergent - value) > epsilon) && 318 (q2 < maxDenominator)) { 319 p0 = p1; 320 p1 = p2; 321 q0 = q1; 322 q1 = q2; 323 a0 = a1; 324 r0 = r1; 325 } else { 326 stop = true; 327 } 328 } while (!stop); 329 330 if (n >= maxIterations) { 331 throw new FractionConversionException(value, maxIterations); 332 } 333 334 if (q2 < maxDenominator) { 335 numerator = BigInteger.valueOf(p2); 336 denominator = BigInteger.valueOf(q2); 337 } else { 338 numerator = BigInteger.valueOf(p1); 339 denominator = BigInteger.valueOf(q1); 340 } 341 } 342 343 /** 344 * Create a fraction given the double value and maximum denominator. 345 * <p> 346 * References: 347 * <ul> 348 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> 349 * Continued Fraction</a> equations (11) and (22)-(26)</li> 350 * </ul> 351 * </p> 352 * 353 * @param value 354 * the double value to convert to a fraction. 355 * @param maxDenominator 356 * The maximum allowed value for denominator. 357 * @throws FractionConversionException 358 * if the continued fraction failed to converge. 359 */ 360 public BigFraction(final double value, final int maxDenominator) 361 throws FractionConversionException { 362 this(value, 0, maxDenominator, 100); 363 } 364 365 /** 366 * <p> 367 * Create a {@link BigFraction} equivalent to the passed <tt>int</tt>, ie 368 * "num / 1". 369 * </p> 370 * 371 * @param num 372 * the numerator. 373 */ 374 public BigFraction(final int num) { 375 this(BigInteger.valueOf(num), BigInteger.ONE); 376 } 377 378 /** 379 * <p> 380 * Create a {@link BigFraction} given the numerator and denominator as simple 381 * <tt>int</tt>. The {@link BigFraction} is reduced to lowest terms. 382 * </p> 383 * 384 * @param num 385 * the numerator. 386 * @param den 387 * the denominator. 388 */ 389 public BigFraction(final int num, final int den) { 390 this(BigInteger.valueOf(num), BigInteger.valueOf(den)); 391 } 392 393 /** 394 * <p> 395 * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1". 396 * </p> 397 * 398 * @param num 399 * the numerator. 400 */ 401 public BigFraction(final long num) { 402 this(BigInteger.valueOf(num), BigInteger.ONE); 403 } 404 405 /** 406 * <p> 407 * Create a {@link BigFraction} given the numerator and denominator as simple 408 * <tt>long</tt>. The {@link BigFraction} is reduced to lowest terms. 409 * </p> 410 * 411 * @param num 412 * the numerator. 413 * @param den 414 * the denominator. 415 */ 416 public BigFraction(final long num, final long den) { 417 this(BigInteger.valueOf(num), BigInteger.valueOf(den)); 418 } 419 420 /** 421 * <p> 422 * Creates a <code>BigFraction</code> instance with the 2 parts of a fraction 423 * Y/Z. 424 * </p> 425 * 426 * <p> 427 * Any negative signs are resolved to be on the numerator. 428 * </p> 429 * 430 * @param numerator 431 * the numerator, for example the three in 'three sevenths'. 432 * @param denominator 433 * the denominator, for example the seven in 'three sevenths'. 434 * @return a new fraction instance, with the numerator and denominator 435 * reduced. 436 * @throws ArithmeticException 437 * if the denominator is <code>zero</code>. 438 */ 439 public static BigFraction getReducedFraction(final int numerator, 440 final int denominator) { 441 if (numerator == 0) { 442 return ZERO; // normalize zero. 443 } 444 445 return new BigFraction(numerator, denominator); 446 } 447 448 /** 449 * <p> 450 * Returns the absolute value of this {@link BigFraction}. 451 * </p> 452 * 453 * @return the absolute value as a {@link BigFraction}. 454 */ 455 public BigFraction abs() { 456 return (BigInteger.ZERO.compareTo(numerator) <= 0) ? this : negate(); 457 } 458 459 /** 460 * <p> 461 * Adds the value of this fraction to the passed {@link BigInteger}, 462 * returning the result in reduced form. 463 * </p> 464 * 465 * @param bg 466 * the {@link BigInteger} to add, must'nt be <code>null</code>. 467 * @return a <code>BigFraction</code> instance with the resulting values. 468 * @throws NullPointerException 469 * if the {@link BigInteger} is <code>null</code>. 470 */ 471 public BigFraction add(final BigInteger bg) { 472 return new BigFraction(numerator.add(denominator.multiply(bg)), denominator); 473 } 474 475 /** 476 * <p> 477 * Adds the value of this fraction to the passed <tt>integer</tt>, returning 478 * the result in reduced form. 479 * </p> 480 * 481 * @param i 482 * the <tt>integer</tt> to add. 483 * @return a <code>BigFraction</code> instance with the resulting values. 484 */ 485 public BigFraction add(final int i) { 486 return add(BigInteger.valueOf(i)); 487 } 488 489 /** 490 * <p> 491 * Adds the value of this fraction to the passed <tt>long</tt>, returning 492 * the result in reduced form. 493 * </p> 494 * 495 * @param l 496 * the <tt>long</tt> to add. 497 * @return a <code>BigFraction</code> instance with the resulting values. 498 */ 499 public BigFraction add(final long l) { 500 return add(BigInteger.valueOf(l)); 501 } 502 503 /** 504 * <p> 505 * Adds the value of this fraction to another, returning the result in 506 * reduced form. 507 * </p> 508 * 509 * @param fraction 510 * the {@link BigFraction} to add, must not be <code>null</code>. 511 * @return a {@link BigFraction} instance with the resulting values. 512 * @throws NullPointerException 513 * if the {@link BigFraction} is <code>null</code>. 514 */ 515 public BigFraction add(final BigFraction fraction) { 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 <tt>roundingMode</tt> 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 <tt>object</tt>, +1 if this is greater 596 * than <tt>object</tt>, 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</code>, 608 * ie "this * 1 / bg", returning the result in reduced form. 609 * </p> 610 * 611 * @param bg 612 * the <code>BigInteger</code> to divide by, must not be 613 * <code>null</code>. 614 * @return a {@link BigFraction} instance with the resulting values. 615 * @throws NullPointerException 616 * if the <code>BigInteger</code> is <code>null</code>. 617 * @throws ArithmeticException 618 * if the fraction to divide by is zero. 619 */ 620 public BigFraction divide(final BigInteger bg) { 621 if (BigInteger.ZERO.equals(bg)) { 622 throw MathRuntimeException.createArithmeticException(FORBIDDEN_ZERO_DENOMINATOR); 623 } 624 return new BigFraction(numerator, denominator.multiply(bg)); 625 } 626 627 /** 628 * <p> 629 * Divide the value of this fraction by the passed <tt>int</tt>, ie 630 * "this * 1 / i", returning the result in reduced form. 631 * </p> 632 * 633 * @param i 634 * the <tt>int</tt> to divide by. 635 * @return a {@link BigFraction} instance with the resulting values. 636 * @throws ArithmeticException 637 * if the fraction to divide by is zero. 638 */ 639 public BigFraction divide(final int i) { 640 return divide(BigInteger.valueOf(i)); 641 } 642 643 /** 644 * <p> 645 * Divide the value of this fraction by the passed <tt>long</tt>, ie 646 * "this * 1 / l", returning the result in reduced form. 647 * </p> 648 * 649 * @param l 650 * the <tt>long</tt> to divide by. 651 * @return a {@link BigFraction} instance with the resulting values. 652 * @throws ArithmeticException 653 * if the fraction to divide by is zero. 654 */ 655 public BigFraction divide(final long l) { 656 return divide(BigInteger.valueOf(l)); 657 } 658 659 /** 660 * <p> 661 * Divide the value of this fraction by another, returning the result in 662 * reduced form. 663 * </p> 664 * 665 * @param fraction 666 * the fraction to divide by, must not be <code>null</code>. 667 * @return a {@link BigFraction} instance with the resulting values. 668 * @throws NullPointerException 669 * if the fraction is <code>null</code>. 670 * @throws ArithmeticException 671 * if the fraction to divide by is zero. 672 */ 673 public BigFraction divide(final BigFraction fraction) { 674 if (BigInteger.ZERO.equals(fraction.numerator)) { 675 throw MathRuntimeException.createArithmeticException(FORBIDDEN_ZERO_DENOMINATOR); 676 } 677 678 return multiply(fraction.reciprocal()); 679 } 680 681 /** 682 * <p> 683 * Gets the fraction as a <tt>double</tt>. This calculates the fraction as 684 * the numerator divided by denominator. 685 * </p> 686 * 687 * @return the fraction as a <tt>double</tt> 688 * @see java.lang.Number#doubleValue() 689 */ 690 @Override 691 public double doubleValue() { 692 return numerator.doubleValue() / denominator.doubleValue(); 693 } 694 695 /** 696 * <p> 697 * Test for the equality of two fractions. If the lowest term numerator and 698 * denominators are the same for both fractions, the two fractions are 699 * considered to be equal. 700 * </p> 701 * 702 * @param other 703 * fraction to test for equality to this fraction, can be 704 * <code>null</code>. 705 * @return true if two fractions are equal, false if object is 706 * <code>null</code>, not an instance of {@link BigFraction}, or not 707 * equal to this fraction instance. 708 * @see java.lang.Object#equals(java.lang.Object) 709 */ 710 @Override 711 public boolean equals(final Object other) { 712 boolean ret = false; 713 714 if (this == other) { 715 ret = true; 716 } else if (other instanceof BigFraction) { 717 BigFraction rhs = ((BigFraction) other).reduce(); 718 BigFraction thisOne = this.reduce(); 719 ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator); 720 } 721 722 return ret; 723 } 724 725 /** 726 * <p> 727 * Gets the fraction as a <tt>float</tt>. This calculates the fraction as 728 * the numerator divided by denominator. 729 * </p> 730 * 731 * @return the fraction as a <tt>float</tt>. 732 * @see java.lang.Number#floatValue() 733 */ 734 @Override 735 public float floatValue() { 736 return numerator.floatValue() / denominator.floatValue(); 737 } 738 739 /** 740 * <p> 741 * Access the denominator as a <code>BigInteger</code>. 742 * </p> 743 * 744 * @return the denominator as a <code>BigInteger</code>. 745 */ 746 public BigInteger getDenominator() { 747 return denominator; 748 } 749 750 /** 751 * <p> 752 * Access the denominator as a <tt>int</tt>. 753 * </p> 754 * 755 * @return the denominator as a <tt>int</tt>. 756 */ 757 public int getDenominatorAsInt() { 758 return denominator.intValue(); 759 } 760 761 /** 762 * <p> 763 * Access the denominator as a <tt>long</tt>. 764 * </p> 765 * 766 * @return the denominator as a <tt>long</tt>. 767 */ 768 public long getDenominatorAsLong() { 769 return denominator.longValue(); 770 } 771 772 /** 773 * <p> 774 * Access the numerator as a <code>BigInteger</code>. 775 * </p> 776 * 777 * @return the numerator as a <code>BigInteger</code>. 778 */ 779 public BigInteger getNumerator() { 780 return numerator; 781 } 782 783 /** 784 * <p> 785 * Access the numerator as a <tt>int</tt>. 786 * </p> 787 * 788 * @return the numerator as a <tt>int</tt>. 789 */ 790 public int getNumeratorAsInt() { 791 return numerator.intValue(); 792 } 793 794 /** 795 * <p> 796 * Access the numerator as a <tt>long</tt>. 797 * </p> 798 * 799 * @return the numerator as a <tt>long</tt>. 800 */ 801 public long getNumeratorAsLong() { 802 return numerator.longValue(); 803 } 804 805 /** 806 * <p> 807 * Gets a hashCode for the fraction. 808 * </p> 809 * 810 * @return a hash code value for this object. 811 * @see java.lang.Object#hashCode() 812 */ 813 @Override 814 public int hashCode() { 815 return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode(); 816 } 817 818 /** 819 * <p> 820 * Gets the fraction as an <tt>int</tt>. This returns the whole number part 821 * of the fraction. 822 * </p> 823 * 824 * @return the whole number fraction part. 825 * @see java.lang.Number#intValue() 826 */ 827 @Override 828 public int intValue() { 829 return numerator.divide(denominator).intValue(); 830 } 831 832 /** 833 * <p> 834 * Gets the fraction as a <tt>long</tt>. This returns the whole number part 835 * of the fraction. 836 * </p> 837 * 838 * @return the whole number fraction part. 839 * @see java.lang.Number#longValue() 840 */ 841 @Override 842 public long longValue() { 843 return numerator.divide(denominator).longValue(); 844 } 845 846 /** 847 * <p> 848 * Multiplies the value of this fraction by the passed 849 * <code>BigInteger</code>, returning the result in reduced form. 850 * </p> 851 * 852 * @param bg 853 * the <code>BigInteger</code> to multiply by. 854 * @return a <code>BigFraction</code> instance with the resulting values. 855 * @throws NullPointerException 856 * if the bg is <code>null</code>. 857 */ 858 public BigFraction multiply(final BigInteger bg) { 859 return new BigFraction(bg.multiply(numerator), denominator); 860 } 861 862 /** 863 * <p> 864 * Multiply the value of this fraction by the passed <tt>int</tt>, returning 865 * the result in reduced form. 866 * </p> 867 * 868 * @param i 869 * the <tt>int</tt> to multiply by. 870 * @return a {@link BigFraction} instance with the resulting values. 871 */ 872 public BigFraction multiply(final int i) { 873 return multiply(BigInteger.valueOf(i)); 874 } 875 876 /** 877 * <p> 878 * Multiply the value of this fraction by the passed <tt>long</tt>, 879 * returning the result in reduced form. 880 * </p> 881 * 882 * @param l 883 * the <tt>long</tt> to multiply by. 884 * @return a {@link BigFraction} instance with the resulting values. 885 */ 886 public BigFraction multiply(final long l) { 887 return multiply(BigInteger.valueOf(l)); 888 } 889 890 /** 891 * <p> 892 * Multiplies the value of this fraction by another, returning the result in 893 * reduced form. 894 * </p> 895 * 896 * @param fraction 897 * the fraction to multiply by, must not be <code>null</code>. 898 * @return a {@link BigFraction} instance with the resulting values. 899 * @throws NullPointerException 900 * if the fraction is <code>null</code>. 901 */ 902 public BigFraction multiply(final BigFraction fraction) { 903 if (numerator.equals(BigInteger.ZERO) || 904 fraction.numerator.equals(BigInteger.ZERO)) { 905 return ZERO; 906 } 907 return new BigFraction(numerator.multiply(fraction.numerator), 908 denominator.multiply(fraction.denominator)); 909 } 910 911 /** 912 * <p> 913 * Return the additive inverse of this fraction, returning the result in 914 * reduced form. 915 * </p> 916 * 917 * @return the negation of this fraction. 918 */ 919 public BigFraction negate() { 920 return new BigFraction(numerator.negate(), denominator); 921 } 922 923 /** 924 * <p> 925 * Gets the fraction percentage as a <tt>double</tt>. This calculates the 926 * fraction as the numerator divided by denominator multiplied by 100. 927 * </p> 928 * 929 * @return the fraction percentage as a <tt>double</tt>. 930 */ 931 public double percentageValue() { 932 return (numerator.divide(denominator)).multiply(ONE_HUNDRED_DOUBLE).doubleValue(); 933 } 934 935 /** 936 * <p> 937 * Returns a <tt>integer</tt> whose value is 938 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 939 * </p> 940 * 941 * @param exponent 942 * exponent to which this <code>BigInteger</code> is to be 943 * raised. 944 * @return <tt>this<sup>exponent</sup></tt>. 945 */ 946 public BigFraction pow(final int exponent) { 947 if (exponent < 0) { 948 return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent)); 949 } 950 return new BigFraction(numerator.pow(exponent), denominator.pow(exponent)); 951 } 952 953 /** 954 * <p> 955 * Returns a <code>BigFraction</code> whose value is 956 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 957 * </p> 958 * 959 * @param exponent 960 * exponent to which this <code>BigFraction</code> is to be raised. 961 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>. 962 */ 963 public BigFraction pow(final long exponent) { 964 if (exponent < 0) { 965 return new BigFraction(MathUtils.pow(denominator, -exponent), 966 MathUtils.pow(numerator, -exponent)); 967 } 968 return new BigFraction(MathUtils.pow(numerator, exponent), 969 MathUtils.pow(denominator, exponent)); 970 } 971 972 /** 973 * <p> 974 * Returns a <code>BigFraction</code> whose value is 975 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 976 * </p> 977 * 978 * @param exponent 979 * exponent to which this <code>BigFraction</code> is to be raised. 980 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>. 981 */ 982 public BigFraction pow(final BigInteger exponent) { 983 if (exponent.compareTo(BigInteger.ZERO) < 0) { 984 final BigInteger eNeg = exponent.negate(); 985 return new BigFraction(MathUtils.pow(denominator, eNeg), 986 MathUtils.pow(numerator, eNeg)); 987 } 988 return new BigFraction(MathUtils.pow(numerator, exponent), 989 MathUtils.pow(denominator, exponent)); 990 } 991 992 /** 993 * <p> 994 * Returns a <code>double</code> whose value is 995 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. 996 * </p> 997 * 998 * @param exponent 999 * exponent to which this <code>BigFraction</code> is to be raised. 1000 * @return <tt>this<sup>exponent</sup></tt>. 1001 */ 1002 public double pow(final double exponent) { 1003 return Math.pow(numerator.doubleValue(), exponent) / 1004 Math.pow(denominator.doubleValue(), exponent); 1005 } 1006 1007 /** 1008 * <p> 1009 * Return the multiplicative inverse of this fraction. 1010 * </p> 1011 * 1012 * @return the reciprocal fraction. 1013 */ 1014 public BigFraction reciprocal() { 1015 return new BigFraction(denominator, numerator); 1016 } 1017 1018 /** 1019 * <p> 1020 * Reduce this <code>BigFraction</code> to its lowest terms. 1021 * </p> 1022 * 1023 * @return the reduced <code>BigFraction</code>. It doesn't change anything if 1024 * the fraction can be reduced. 1025 */ 1026 public BigFraction reduce() { 1027 final BigInteger gcd = numerator.gcd(denominator); 1028 return new BigFraction(numerator.divide(gcd), denominator.divide(gcd)); 1029 } 1030 1031 /** 1032 * <p> 1033 * Subtracts the value of an {@link BigInteger} from the value of this one, 1034 * returning the result in reduced form. 1035 * </p> 1036 * 1037 * @param bg 1038 * the {@link BigInteger} to subtract, must'nt be 1039 * <code>null</code>. 1040 * @return a <code>BigFraction</code> instance with the resulting values. 1041 * @throws NullPointerException 1042 * if the {@link BigInteger} is <code>null</code>. 1043 */ 1044 public BigFraction subtract(final BigInteger bg) { 1045 return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator); 1046 } 1047 1048 /** 1049 * <p> 1050 * Subtracts the value of an <tt>integer</tt> from the value of this one, 1051 * returning the result in reduced form. 1052 * </p> 1053 * 1054 * @param i 1055 * the <tt>integer</tt> to subtract. 1056 * @return a <code>BigFraction</code> instance with the resulting values. 1057 */ 1058 public BigFraction subtract(final int i) { 1059 return subtract(BigInteger.valueOf(i)); 1060 } 1061 1062 /** 1063 * <p> 1064 * Subtracts the value of an <tt>integer</tt> from the value of this one, 1065 * returning the result in reduced form. 1066 * </p> 1067 * 1068 * @param l 1069 * the <tt>long</tt> to subtract. 1070 * @return a <code>BigFraction</code> instance with the resulting values, or 1071 * this object if the <tt>long</tt> is zero. 1072 */ 1073 public BigFraction subtract(final long l) { 1074 return subtract(BigInteger.valueOf(l)); 1075 } 1076 1077 /** 1078 * <p> 1079 * Subtracts the value of another fraction from the value of this one, 1080 * returning the result in reduced form. 1081 * </p> 1082 * 1083 * @param fraction 1084 * the {@link BigFraction} to subtract, must not be 1085 * <code>null</code>. 1086 * @return a {@link BigFraction} instance with the resulting values 1087 * @throws NullPointerException 1088 * if the fraction is <code>null</code>. 1089 */ 1090 public BigFraction subtract(final BigFraction fraction) { 1091 if (ZERO.equals(fraction)) { 1092 return this; 1093 } 1094 1095 BigInteger num = null; 1096 BigInteger den = null; 1097 if (denominator.equals(fraction.denominator)) { 1098 num = numerator.subtract(fraction.numerator); 1099 den = denominator; 1100 } else { 1101 num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator)); 1102 den = denominator.multiply(fraction.denominator); 1103 } 1104 return new BigFraction(num, den); 1105 1106 } 1107 1108 /** 1109 * <p> 1110 * Returns the <code>String</code> representing this fraction, ie 1111 * "num / dem" or just "num" if the denominator is one. 1112 * </p> 1113 * 1114 * @return a string representation of the fraction. 1115 * @see java.lang.Object#toString() 1116 */ 1117 @Override 1118 public String toString() { 1119 String str = null; 1120 if (BigInteger.ONE.equals(denominator)) { 1121 str = numerator.toString(); 1122 } else if (BigInteger.ZERO.equals(numerator)) { 1123 str = "0"; 1124 } else { 1125 str = numerator + " / " + denominator; 1126 } 1127 return str; 1128 } 1129 1130 /** {@inheritDoc} */ 1131 public BigFractionField getField() { 1132 return BigFractionField.getInstance(); 1133 } 1134 1135 }