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