1
import java.math.BigInteger;

public class Rational extends Number implements Comparable {
  // Data fields for numerator and denominator
  private BigInteger numerator = new BigInteger("0");
  private BigInteger denominator = new BigInteger("1");

  /** Construct a rational with default properties */
  public Rational() {
    this(BigInteger.valueOf(0), BigInteger.valueOf(1));
  }

  /** Construct a rational with specified numerator and denominator */ 
  public Rational(BigInteger numerator, BigInteger denominator) {
    BigInteger gcd = gcd(numerator, denominator);
    this.numerator = BigInteger.valueOf(denominator.signum()).multiply(numerator).divide(gcd);
    this.denominator = this.denominator.abs().divide(gcd); 
  }

  /** Find GCD of two numbers */ 
  private static BigInteger gcd(BigInteger n, BigInteger d) {
    BigInteger n1 = n.abs();
    BigInteger n2 = d.abs();
    BigInteger gcd = new BigInteger("1");

    for (int k = 1; k <= n1.intValue() && k <= n2.intValue(); k++) {
      if (n1.intValue() % k == 0 && n2.intValue() % k == 0)
        gcd = BigInteger.valueOf(k);
    }

    return gcd;
  }

  /** Return numerator */
  public BigInteger getNumerator() {
    return numerator;
  }

  /** Return denominator */
  public BigInteger getDenominator() {
    return denominator;
  }

  /** Add a rational number to this rational */
  public Rational add(Rational secondRational) {
    BigInteger n = (numerator.multiply(secondRational.getDenominator())).add(denominator.multiply(secondRational.getNumerator()));
    BigInteger d = denominator.multiply(secondRational.getDenominator());
    return new Rational(n, d); 
  }

  /** Subtract a rational number from this rational */
  public Rational subtract(Rational secondRational) {
    BigInteger n = (numerator.multiply(secondRational.getDenominator())).subtract(denominator.multiply(secondRational.getNumerator()));
    BigInteger d = denominator.multiply(secondRational.getDenominator());
    return new Rational(n, d);
  }

  /** Multiply a rational number to this rational */
  public Rational multiply(Rational secondRational) {
    BigInteger n = numerator.multiply(secondRational.getNumerator());
    BigInteger d = denominator.multiply(secondRational.getDenominator());
    return new Rational(n, d);
  }

  /** Divide a rational number from this rational */
  public Rational divide(Rational secondRational) {
    BigInteger n = numerator.multiply(secondRational.getDenominator());
    BigInteger d = denominator.multiply(secondRational.numerator);
    return new Rational(n, d);
  }

  /** Override the toString() method */
  public String toString() {
    if (denominator.intValue() == 1)
      return numerator + "";
    else
      return numerator + "/" + denominator;
  }

  /** Override the equals method in the Object class */


  public boolean equals(Object parm1) {
    if ((this.subtract((Rational)(parm1)).getNumerator()).intValue() == 0) 
        return true;
    else
      return false;
  }

  /** Override the abstract intValue method in java.lang.Number */
  public int intValue() {
    return (int)doubleValue();
  }

  /** Override the abstract floatValue method in java.lang.Number */
  public float floatValue() {
    return (float)doubleValue();
  }

  /** Override the doubleValue method in java.lang.Number */
  public double doubleValue() {
    return numerator.divide(denominator).doubleValue();
  }

  /** Override the abstract BigIntegerValue method in java.lang.Number */
  public long longValue() {
    return (long)doubleValue();
  }

  /** Override the compareTo method in java.lang.Comparable */
  public int compareTo(Object o) {
    if (((this.subtract((Rational)o)).getNumerator()).intValue() > 0)
      return 1;
    else if (((this.subtract((Rational)o)).getNumerator()).intValue() < 0)
      return -1;
    else
      return 0;
  }

  public static void main(String[] args) {
    // Create and initialize two rational numbers r1 and r2.
    Rational r1 = new Rational(BigInteger.valueOf(1), BigInteger.valueOf(2));
    Rational r2 = new Rational(BigInteger.valueOf(1), BigInteger.valueOf(2));

    for (int i = 2; i <= 100; i++){
        r2.numerator = BigInteger.valueOf(i);
        r2.denominator = r2.denominator.add(BigInteger.valueOf(1));


        System.out.println("r2: " + r2.getNumerator() + "/" + r2.getDenominator());

        r1 = r1.add(r2);        
    }
    // Display results 

    System.out.println("r1: " + r1.getNumerator() + "/" + r1.getDenominator());
  }

我已经为此工作了几个小时,但我绝对碰壁了。目标是使用 BigInteger 对一系列分数求和。由于某种原因,当 r2 的分子和分母应该是 1/2 时,它们是相等的。最终结果也不正确,因为分母不应该是 0。我错过了什么,或者我做错了什么?

4

1 回答 1

1

问题是这一行:

this.denominator = this.denominator.abs().divide(gcd); 

改成:

this.denominator = denominator.abs().divide(gcd); 

第一个总是使用 1 作为分母,因为这就是它的初始化方式。

但是,您的 gcd 实现非常低效......

于 2011-11-09T05:34:18.557 回答