# BigInteger Rational (CS106A-Stanford university)

Printable View

• 09-27-2010, 02:55 PM
ccie007
BigInteger Rational (CS106A-Stanford university)
Hi Folks,
This is the exercise iam trying to solve from the book "Art and science of Java":

Quote:

The implementation of the Rational class given in this chapter is not particularly useful in practice because it doesn’t allow the numerator and denominator to exceed the size of an integer, even though larger values tend to occur quite often in rational arithmetic. One way to avoid the problem is to use the BigInteger class in the java.math package, which defines an extended type of integer that can take on arbitrarily large values. Rewrite the implementation of Rational so that the private instance variables num and den are declared as BigIntegers instead of ints, but without changing the argument and result types of any of the public methods. To
learn how BigInteger works, consult the javadoc page.
This is the actual Rational class from the chapter:

Code:

```import acm.util.*; /** * The Rational class is used to represent rational numbers, which * are defined to be the quotient of two integers. */ public class Rational { /** * Creates a new Rational initialized to zero. */ public Rational() { this(0); } /** * Creates a new Rational from the integer argument. * @param n The initial value */ public Rational(int n) { this(n, 1); } /** * Creates a new Rational with the value x / y. * @param x The numerator of the rational number * @param y The denominator of the rational number */ public Rational(int x, int y) { if (y == 0) throw new ErrorException("Division by 0"); int g = gcd(Math.abs(x), Math.abs(y)); num = x / g; den = Math.abs(y) / g; if (y < 0) num = -num; } /** * Adds the rational number r to this one and returns the sum. * @param r The rational number to be added * @return The sum of the current number and r */ public Rational add(Rational r) { return new Rational(this.num * r.den + r.num * this.den, this.den * r.den); } /** * Subtracts the rational number r from this one. * @param r The rational number to be subtracted * @return The result of subtracting r from the current number */ public Rational subtract(Rational r) { return new Rational(this.num * r.den - r.num * this.den, this.den * r.den); }/** * Multiplies this number by the rational number r. * @param r The rational number used as a multiplier * @return The result of multiplying the current number by r */ public Rational multiply(Rational r) { return new Rational(this.num * r.num, this.den * r.den); } /** * Divides this number by the rational number r. * @param r The rational number used as a divisor * @return The result of dividing the current number by r */ public Rational divide(Rational r) { return new Rational(this.num * r.den, this.den * r.num); } /** * Creates a string representation of this rational number. * @return The string representation of this rational number */ public String toString() { if (den == 1) { return "" + num; } else { return num + "/" + den; } } /** * Calculates the greatest common divisor using Euclid's algorithm. * @param x First integer * @param y Second integer * @return The greatest common divisor of x and y */ private int gcd(int x, int y) { int r = x % y; while (r != 0) { x = y; y = r; r = x % y; } return y; } /* Private instance variables */ private int num; /* The numerator of this Rational */ private int den; /* The denominator of this Rational */ }```
And this my code at the moment:
Code:

```import java.math.BigInteger; import acm.util.*; import java.util.*; import java.math.*; /** * The Rational class is used to represent rational numbers, which * are defined to be the quotient of two integers. */             public class Rational {             /**         * Main method         * @param arg         */                 public static void main (String[]arg){                         Rational a = new Rational(1,4);             Rational b = new Rational(1,4);             Rational c = new Rational(1,6);             Rational sum = a.add(b).add(c);             System.out.println(a + " + " + b + " + " + c + " = " + sum);             }         /**     * Creates a new Rational initialized to zero.     */     public Rational() {     this(0);     }     /**     * Creates a new Rational from the integer argument.     * @param n The initial value     */     public Rational(int n) {     this(n, 1);     }     /**     * Creates a new Rational with the value x / y.     * @param x The numerator of the rational number     * @param y The denominator of the rational number     */     public Rational(int x, int y) {     if (y == 0) throw new ErrorException("Division by 0");     int g = gcd(Math.abs(x), Math.abs(y));     BigInteger num = BigInteger.valueOf(x / g);     BigInteger den = BigInteger.valueOf( Math.abs(y) / g);     if (y < 0) num = -num;     }     /**     * Adds the rational number r to this one and returns the sum.     * @param r The rational number to be added     * @return The sum of the current number and r     */     public Rational add(Rational r) {                     return new Rational(this.num.multiply(r.den) + r.num.multiply(this.den),             this.den.multiply(r.den));                 }     /**     * Subtracts the rational number r from this one.     * @param r The rational number to be subtracted     * @return The result of subtracting r from the current number     */     public Rational subtract(Rational r) {     return new Rational(this.num.multiply( r.den) - r.num .multiply( this.den),     this.den.multiply( r.den));     }         /**     * Multiplies this number by the rational number r.     * @param r The rational number used as a multiplier     * @return The result of multiplying the current number by r     */     public Rational multiply(Rational r) {     return new Rational(this.num.multiply(r.num), this.den.multiply(r.den));     }     /**     * Divides this number by the rational number r.     * @param r The rational number used as a divisor     * @return The result of dividing the current number by r     */     public Rational divide(Rational r) {     return new Rational(this.num.multiply(r.den), this.den.multiply(r.num));     }     /**     * Creates a string representation of this rational number.     * @return The string representation of this rational number     */     public String toString() {     if (den == 1) {     return "" + num;     } else {     return num + "/" + den;     }     }     /**     * Calculates the greatest common divisor using Euclid's algorithm.     * @param x First integer     * @param y Second integer     * @return The greatest common divisor of x and y     */     private int gcd(int x, int y) {     int r = x % y;     while (r != 0) {     x = y;     y = r;     r = x % y;     }     return y;     }     /* Private instance variables */     private BigInteger num; /* The numerator of this Rational */     private BigInteger den; /* The denominator of this Rational */     }```
Can anybody give me hints what I need to do resolve this.I want to learn and do it by myself.

Thank you all so much.
• 09-27-2010, 03:26 PM
Tolls
Use the CODE tag for code (like you did for the first chunk of code you gave us) otherwise you lose any formatting.

So, what's your question?
What problem do you have?
• 09-27-2010, 04:27 PM
ccie007
Code:

``` private BigInteger num; /* The numerator of this Rational */   private BigInteger den; /* The denominator of this Rational */     }```
I have changed "int" to "BigInteger" in the above lines to resolve the exercise.

changed this lines
Code:

```num = x / g; den = Math.abs(y) / g;```
to this.But not sure I did it right or not.Eclipse editor doesn't complain while compiling.
Code:

```BigInteger num = BigInteger.valueOf(x / g);     BigInteger den = BigInteger.valueOf( Math.abs(y) / g);```
Tuff part is changing this

Code:

```public Rational add(Rational r) { return new Rational(this.num * r.den + r.num * this.den, this.den * r.den);```
to this :

Code:

```public Rational add(Rational r) {                     return new Rational(this.num.multiply(r.den) + r.num.multiply(this.den),             this.den.multiply(r.den));```
The compiler say there are error in "public Rational add" method.I think I am doing it almost right.Any idea matey?
• 09-27-2010, 04:53 PM
Tolls
"this.num.multiply(r.den) + r.num.multiply(this.den)".

It's that "+" sign. You can't add BigIntegers using "+", you need to use add() (or is it sum()?).

Next time you should print the full error message, otherwise we're left guessing here.
• 09-28-2010, 07:23 PM
ccie007
here is the error message that is comming up in the Eclipse editor

Quote:

Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The operator - is undefined for the argument type(s) BigInteger
The constructor Rational(BigInteger, BigInteger) is undefined
The operator - is undefined for the argument type(s) java.math.BigInteger, java.math.BigInteger
The constructor Rational(BigInteger, BigInteger) is undefined
The constructor Rational(BigInteger, BigInteger) is undefined
Incompatible operand types BigInteger and int

at Rational.<init>(Rational.java:50)
at Rational.main(Rational.java:20)

By the way can u explain what BigInteger is for? .I know it roughly.
• 09-28-2010, 07:29 PM
JosAH
Quote:

Originally Posted by ccie007
By the way can u explain what BigInteger is for? .I know it roughly.

You´re kidding us right?

kind regards,

Jos
• 09-28-2010, 07:33 PM
Norm
Quote:

operator - is undefined for the argument type(s) BigInteger
Because the operands are objects and not primitives, you need to use methods to do arithmetic with BigInteger objects. See post#4
• 09-28-2010, 07:52 PM
ccie007
No dude I am not kidding. I do not know bigInteger clearly.I know when using biginteger instead of integer we can't use +,-,/ etc rather we have to use add,multiply.But Why do use biginteger instead of integer in the first place.Is it because memory can't hold long decimal numbers like 13.0000000000000000000000000.
• 09-28-2010, 08:30 PM
Zack
The documentation is amazing:
BigInteger (Java 2 Platform SE v1.4.2)

If that's a little much for you, you can read the second reply in this thread, but it points to the documentation as well.
• 09-28-2010, 08:37 PM
ccie007
Can anybody explain to me plz.I tried reading the java doc but found it quite hard to understand.
• 09-28-2010, 08:41 PM
Zack
You didn't even click the second link... did you?

Quote:

Originally Posted by http://www.coderanch.com/t/408968/java/java/difference-between-Integer-BigInteger
Now coming to the BigInteger, you would use it in calculations which deal with very large numbers.The use of BigIntegers is in Security where typically it is used for keys specifications.

Here's more information on the range of the types: Java: java.math.BigInteger
• 09-28-2010, 08:54 PM
ccie007
Now I get more ideas with regards to BigInteger by reading this
Big Integers
• 09-29-2010, 07:57 PM
ccie007
Still can't resolve this exeriece.This sam exercise has been discussed before on this forum but I do not want look at it yet.Because I do not want copy others work.

Please guys some one give me any clues how to resolve this exercise.If I learn this way rather than looking at somebody's work I believe I will learn more.Cheers mates.
• 09-29-2010, 09:56 PM
Norm
What is your problem now? Are there compiler errors? Execution errors or logic errors (wrong output)?
• 10-01-2010, 05:42 PM
ccie007
Yay, I resolved the exerice by myself.Thank you guys for your kind support.Here is my final code:
Code:

```import java.math.BigInteger; import acm.util.*; import java.util.*; import java.math.*; /** * The Rational class is used to represent rational numbers, which * are defined to be the quotient of two integers. */             public class Rational {             /**         * Main method         * @param arg         */         static final BigInteger ONE = new BigInteger("1");         static final BigInteger ZERO = new BigInteger("0");         static final BigInteger FOUR = new BigInteger("4");         static final BigInteger SIX = new BigInteger("6");         static final BigInteger TWO = new BigInteger("2");                                     public static void main (String[]arg){                         Rational a = new Rational(ONE,FOUR);             Rational b = new Rational(ONE,FOUR);             Rational c = new Rational(ONE,SIX);             Rational sum = a.add(b).add(c);             System.out.println(a + " + " + b + " + " + c + " = " + sum);             }         /**     * Creates a new Rational initialized to zero.     */     public Rational() {     this(ZERO);     }     /**     * Creates a new Rational from the integer argument.     * @param n The initial value     */     public Rational(BigInteger n) {     this(n, ONE);     }     /**     * Creates a new Rational with the value x / y.     * @param x The numerator of the rational number     * @param y The denominator of the rational number     */     public Rational(BigInteger x, BigInteger y) {     if (y.signum() == 0) throw new ErrorException("Division by 0");     BigInteger g = gcd(abs(x),abs(y));     num = x.divide(g);     den =abs(y).divide(g);     if (y.signum()==-1)         num = num.subtract(num.multiply(TWO));     }     /**     * Adds the rational number r to this one and returns the sum.     * @param r The rational number to be added     * @return The sum of the current number and r     */     public Rational add(Rational r) {                     return new Rational(this.num.multiply(r.den).add( r.num.multiply(this.den)),             this.den.multiply(r.den));                 }     /**     * Subtracts the rational number r from this one.     * @param r The rational number to be subtracted     * @return The result of subtracting r from the current number     */     public Rational subtract(Rational r) {     return new Rational(this.num.multiply( r.den).subtract( r.num .multiply( this.den)),     this.den.multiply( r.den));     }         /**     * Multiplies this number by the rational number r.     * @param r The rational number used as a multiplier     * @return The result of multiplying the current number by r     */     public Rational multiply(Rational r) {     return new Rational(this.num.multiply(r.num), this.den.multiply(r.den));     }     /**     * Divides this number by the rational number r.     * @param r The rational number used as a divisor     * @return The result of dividing the current number by r     */     public Rational divide(Rational r) {     return new Rational(this.num.multiply(r.den), this.den.multiply(r.num));     }     /**     * Creates a string representation of this rational number.     * @return The string representation of this rational number     */     public String toString() {     if (den.equals(ONE)) {     return "" + num;     } else {     return num + "/" + den;     }     }     /**     * Calculates the greatest common divisor using Euclid's algorithm.     * @param x First integer     * @param y Second integer     * @return The greatest common divisor of x and y     */     private BigInteger gcd(BigInteger x, BigInteger y) {     BigInteger r = abs(x).mod(abs(y));     while (r.signum()==1) {     x = y;     y = r;     r = abs(x).mod(abs(y));     }     return y;     }     private BigInteger abs(BigInteger x) {         // TODO Auto-generated method stub         return x;     }     /* Private instance variables */     private BigInteger num; /* The numerator of this Rational */     private BigInteger den; /* The denominator of this Rational */     }```
• 10-01-2010, 07:09 PM
ccie007
Can anybody explain me what is happening behind this part of the code please.

Code:

```     /**     * Creates a new Rational initialized to zero.     */     public Rational() {     this(ZERO);     }     /**     * Creates a new Rational from the integer argument.     * @param n The initial value     */     public Rational(BigInteger n) {     this(n, ONE);     }     /**     * Creates a new Rational with the value x / y.     * @param x The numerator of the rational number     * @param y The denominator of the rational number     */     public Rational(BigInteger x, BigInteger y) {     if (y.signum() == 0) throw new ErrorException("Division by 0");     BigInteger g = gcd(abs(x),abs(y));     num = x.divide(g);     den =abs(y).divide(g);     if (y.signum()==-1)         num = num.subtract(num.multiply(TWO));     }     /**```
I know about numerator and denomenator being divided by gcd bit but I am confused with what those three contructors are doing.

Here is the explanation from the book for those three constructors but I still can't understand it, it may because it is short explanation.Can anybody elaborate for me please:
Quote:

• Multiple constructors: The Rational class in Figure 6-9 defines three different
constructors. Calling new Rational() creates a new rational number whose value is
0, which is represented internally as the fraction 0 / 1. Calling new Rational(n)
creates a new rational number equal to the integer n, which is simply the fraction n / 1.
Finally, calling new Rational(x, y) creates a new rational number equal to the
fraction x / y.
• 10-01-2010, 07:16 PM
Norm
It looks like each constructor starting at the top calls the next one down.
the 'this' is a call to a constructor.
So this(ZERO) in the no arg constructor calls the constructor with a single arg