Hello everybody.
I'm having some problems understanding Overflow.
I was solving the following exercise:
Use the Rational class with long values) Write a program that
computes the following summation series using the Rational class:
1/2 + 2/3 + 3/4 + ... + 98/99 + 99/100
You will discover that the output is incorrect because
of integer overflow (too large).
To fix this problem, see Programming Exercise 13.15 (Rational Class using BigIntegers)
First of all, when I run the program it produces integer overflow.
Also, the program is very slow to complete the task.
It takes 3 minutes and 26 seconds to finish and the program "freezes" during the execution and then it "unfreezes" and then it continues.
The majority of my programs up until now take less than 1 minute to finish.
I was not surprised to see the integer overflow because of the exercise text.
But because the program was taking too long, I´ve tried to see if I wrote something that was slowing down the exeuction of the program.
I was trying to see if I could make the program run faster.
The Rational class is a class that represents a rational number, using a numerator and a denominator.
Both the numerator and the denominator are long variables.
The Rational class extends the Number Class and implements the Comparable Interface for <Rational>.
I've changed the Rational Class in the book in several ways.
In the Constructor of the Rational Class:
public Rational(long numerator, long denominator) throws Exception
this Constructor throws a Custom Exception I've created:
The Rational Class has a method doubleValue() that overrides the method in the Number class.
The method doubleValue() returns the value of the Rational Numerator/Denominator as a double.
/* Implement the abstract doubleValue method in Number */ @Override public double doubleValue() { return getNumerator() * 1.0 / getDenominator(); }
The testSummation class is the Test Class.
I start by defining the variables.
int currentNumerator;
int currentDenominator;
double fractionsSum;
Then I create the object sum and initiase the variables
currentNumerator = 1;
currentDenominator = 2;
//Create and initialize two rational number sum
Rational sum;
sum = new Rational(currentNumerator, currentDenominator);
fractionsSum = (double)currentNumerator/(double)currentDenominator;
At this moment, both the double values of sum (Rational object) and fractionsSum (double variable) are the same.
Then we have a While loop and I also write here what is afte the while loop
while(currentNumerator < 99) { currentNumerator++; currentDenominator++; fractionsSum += (double)currentNumerator/(double)currentDenominator; System.out.println("Current Numerator " + currentNumerator + " and current Denominator " + currentDenominator); System.out.println("The current value of the sum using " + "Current Numerator and current Denominator is " + fractionsSum); sum = sum.add( new Rational( currentNumerator, currentDenominator) ); System.out.println("The current value of the sum using " + "Rational Class is " + sum.doubleValue()); } //end of while(currentNumerator < 100) System.out.println("The result of the sum using the sum of doubles is " + fractionsSum); System.out.println("The result of the sum using the Rational class is " + sum.doubleValue());
I would like to say that I've already tested the program by removing the Rational class, that is by just using the fractionsSum variable inside the while loop and the program is much faster.
Also the overflow only happens in the Rational class.
I already know some situations where overflow happens.
For example the maximum value of an integer is:
2147483647
So if i have:
int a = 100000;
int b = a;
int c = a;
int d;
d = a * b * c;
this will produce overflow because the multiplication exceeds the maximum for int.
But in the programs I created, I don't understand why the overflow happens.
And I don't understand why the overflow happens in the object of the Rational class and why it does not happen in the primitive double variable.
This is the output and as you can see the values start the same for sum object and fractionsSum double variable.
There are some variations at the last number due to the calculation methods used.
Then, at Current Numerator 24 and current Denominator 25 the sum object starts overflowing but the double variable stays fine.
Current Numerator 20 and current Denominator 21
The current value of the sum using Current Numerator and current Denominator is 17.354641295237272
The current value of the sum using Rational Class is 17.354641295237272
Current Numerator 21 and current Denominator 22
The current value of the sum using Current Numerator and current Denominator is 18.309186749782725
The current value of the sum using Rational Class is 18.309186749782725
Current Numerator 22 and current Denominator 23
The current value of the sum using Current Numerator and current Denominator is 19.26570848891316
The current value of the sum using Rational Class is 19.26570848891316
Current Numerator 23 and current Denominator 24
The current value of the sum using Current Numerator and current Denominator is 20.22404182224649
The current value of the sum using Rational Class is 20.224041822246495
Current Numerator 24 and current Denominator 25
The current value of the sum using Current Numerator and current Denominator is 21.184041822246492
The current value of the sum using Rational Class is 2.244902106795326
Current Numerator 25 and current Denominator 26
The current value of the sum using Current Numerator and current Denominator is 22.145580283784952
The current value of the sum using Rational Class is -6.706479358929753
Current Numerator 26 and current Denominator 27
The current value of the sum using Current Numerator and current Denominator is 23.108543246747914
The current value of the sum using Rational Class is -2.033851687488958
So, I have a few questions:
What is Overflow?
In which situations Overflow might happen?
In these programs why do we have overflow in the object of the Rational class ?
In these programs, why is it that the double variable does not Overflow ?
Why is it that the program takes so long to run with the object of the Rational class, but is much faster using only primitives ?
Thank you,
Rogério