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