Problem
Given two integers a, b, a < b. Display its decimal expansion. You will print the decimal expansion of integer quotient given, stopping just as the expansion terminates or just as the repeating pattern is to repeat itself for the first time. If there is a repeating pattern, you will say how many of digits are in the repeating pattern.Sample Input
3 7
345 800
112 990
53 122Sample Output
.428751
The last 6 digits repeat forever.
.43125
This expansion terminates.
.113
The last 2 digits repeat forever.
.4344262295081967213114754098360655737704918032786885245901639
The last 60 digits repeat forever.
Note: This problem is original from the ProgFest programming contest.
The algorithm for this problem is not difficult if we apply these three theorems:
However, the problem that I'm facing is the rounding-off when calculating alpha using the recursive formula given in Theorem 1. The display function is defined as follows:
void displayFraction( int n, int d, int length ) {
std::cout << ".";
double alpha = static_cast<double>( n ) / d;
for( int i = 1; i <= length; ++i ) {
int c = std::floor( 10.0 * alpha );
alpha = 10.0 * alpha - c;
std::cout << c;
}
}
And my output was:
.4344 2622 9508 1967 3732 7807 5683 6291 4025 7835 3881 8359 3750 0000 0000 0
where the problem output was:
.4344 2622 9508 1967 2131 1475 4098 3606 5573 7704 9180 3278 6885 2459 0163 9
As you can see, it was correct up to the 16th digit. So my question is, how I can prevent the truncating digits when performing the calculation in this particular situation? Any idea?
The problem is that double
doesn't have infinite amounts of precision, but instead can only manage about 16 decimal digits worth. Which is where you run into trouble (funny, that!) as the fundamental lack of information in the input double
shows up.
You need to find a way of tackling the problem that will keep getting closer to the answer as you get more digits out of it. That means you'll need to think much more about Theorem 3, and also work on writing your code in terms of rationals instead of floating point.
Use a bignum library like gmp. There's only so much information you can pack into a double.
I think you want an arbitrary precision library
Something like the gnu MP bignum, although other flavours are available
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With