2011-11-09 55 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使用long到BigInteger的重写。我遇到的问题是分母间歇性地变为零。 – MISMajorDeveloperAnyways

回答

1

的问题是这一行:

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

更改为:

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

第一个总是使用1作为分母因为这是它如何初始化。

但是,你的gcd实现是非常不够...

+0

+1。这是为实例变量和方法参数使用相同名称的缺陷的一个很好的例子。你应该只在简单的制定者中这样做。 – Thilo