开发者

How to display precisely the decimal digits of a double in C++?

开发者 https://www.devze.com 2023-03-19 12:43 出处:网络
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 repe

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 122

Sample 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:

How to display precisely the decimal digits of a double in C++?

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

0

精彩评论

暂无评论...
验证码 换一张
取 消