2011-11-09 7 views
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であってはならないので、最終結果も正しくありません。何が欠けているのですか、何が間違っていますか?BigIntegerを使って系列を計算する

+0

BigInteger.gcdメソッドを使用しないのはなぜですか? –

+1

すべての個々のメソッドについていくつかのJUnitテストを書いて、どのメソッドが動作していないかを調べます。 – Thilo

+0

私はこれに新しいです。このプログラムは、Rationalを長い間BigIntegerを使って書き直したものです。私が抱えている問題は、分母が断続的にゼロになることです。 – MISMajorDeveloperAnyways

答えて

1

問題は、この行です:

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

ことは、それが初期化されています方法ですと最初のものは、常に分母として1を使用しています:へ

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

変更。

しかし、あなたのgcdの実装は非常に不十分です...

+0

+1。これは、インスタンス変数とメソッドパラメータに同じ名前を使用するという落とし穴の良い例です。あなたはシンプルなセッターでのみこれを行う必要があります。 – Thilo

関連する問題