Search code examples
javabigintegerrational-number

About rational number in java programming, to calculate (1/2+3/4+...+99/100)^2


The purpose of this code is to calculate (1/2+3/4+...+99/100)^2. But my loop can't be executed correctly. The result of r1 is 3/4 instead of 99/100, what's wrong with my code? I think my loop can be run because the y I can get it correctly. So how can i correct my code and make it able to calculate (1/2+3/4+...+99/100)^2 ? Thank you for answering.

import java.math.BigInteger;

public class Rational {
// Data fields for numerator and denominator
private BigInteger numerator = BigInteger.ZERO;
private BigInteger denominator = BigInteger.ONE;


/** Construct a rational with default properties */
public Rational() {
this(BigInteger.ZERO, BigInteger.ONE);
}

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

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

 for (int k = 1; (new BigInteger(String.valueOf(k))).compareTo(n1)<=0 && 
 (new BigInteger(String.valueOf(k))).compareTo(n2)<=0; k++) {
 if (n1.mod(new BigInteger(String.valueOf(k))).equals(BigInteger.ZERO) && 
 n2.mod(new BigInteger(String.valueOf(k))).equals(BigInteger.ZERO)) 
 gcd = 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(sec
ondRational.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);
 }

/** Compute the square of this rational number*/
 public Rational square() {
     BigInteger n = numerator.multiply(numerator);
     BigInteger d = denominator.multiply(denominator);
  return new Rational(n, d);
 }

/** toString */
 public String toString() {
      return numerator + "/" + denominator;
 }
}

and this is the testRational class import java.math.BigInteger;

public class TestRational {
   public static void main(String[]args){
    int y = 1;

    BigInteger i=new BigInteger(String.valueOf(1));
    BigInteger a=new BigInteger(String.valueOf(2));
    BigInteger b=new BigInteger(String.valueOf(3));
    BigInteger c=new BigInteger(String.valueOf(5));



    Rational sum = new  Rational(BigInteger.ZERO,a);
    Rational r0 = new Rational(b,b.add(i));
    Rational r2 = new  Rational(a,c);
    Rational r3 = new  Rational(a,c);


    Rational s1 = r3.multiply(r2);
    Rational s2 = r3.square();
    Rational s3 = r2.divide(r3);

    Rational r1 = new  Rational(i,a);
    do{

        sum = sum.add(r0);
        b = b.add(a);
        y++;




    }while(y<49);
        System.out.println(sum.multiply(sum));
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
        System.out.println(r0);
}
}

The purpose of this code is to calculate (1/2+3/4+...+99/100)^2. But my loop can't be executed correctly. The result of r1 is 3/4 instead of 99/100, what's wrong with my code? I think my loop can be run because the y I can get it correctly. So how can i correct my code and make it able to calculate (1/2+3/4+...+99/100)^2 ? Thank you for answering. The purpose of this code is to calculate (1/2+3/4+...+99/100)^2. But my loop can't be executed correctly. The result of r1 is 3/4 instead of 99/100, what's wrong with my code? I think my loop can be run because the y I can get it correctly. So how can i correct my code and make it able to calculate (1/2+3/4+...+99/100)^2 ? Thank you for answering.


Solution

  • Let's write it less confusingly, without all the unnecessary stuff and confusing loop. The definition of the sum is (1/2 + 3/4 ... 99/100) so let's start by creating all the fractions in the sum:

    for (int i = 1; i <= 99; i += 2) {
        BigRational t = new BigRational(BigInteger.valueOf(i), BigInteger.valueOf(i + 1));
    }
    

    They have to be summed, so there has to be a variable declared outside the loop to sum up all those fractions into:

    Rational sum = new Rational();
    for (int i = 1; i <= 99; i += 2) {
        Rational t = new Rational(BigInteger.valueOf(i), BigInteger.valueOf(i + 1));
        sum = sum.add(t);
    }
    

    Then square that and you have your answer. I get:

    87593039510089573189394173247956745677798336081
    -----------------------------------------------
       38416307357189261992010230523038591203840000
    

    Which I can't verify but it looks reasonable enough. The expected answer is "a bit less than 502" (because it's the square of 50 terms that are nearly 1, if 0.5 can be called that) and this is close enough.

    By the way, stop using String.valueOf everywhere in Rational. Just work with numbers. And BigInteger already implements gcd, you don't have to write your own (less efficient) version. I had to replace this otherwise it took too long.