问题
给定两个整数a,b,a<湾显示其十进制扩展。您将打印给定的整数商的十进制扩展,就像扩展终止时一样停止,或者就像重复模式第一次重复一样。如果存在重复模式,您将说明重复模式中有多少位数。示例输入
3 7
345 800
112 990
53 122示例输出
0.428751
最后6位数字永远重复 0.43125
这种扩张终止了 .113
最后两位数字永远重复 .4344262295081967213114754098360655737704918032786885245901639
最后60位数字永远重复。
注意:此问题来自ProgFest编程竞赛。
如果我们应用这三个定理,这个问题的算法并不困难:
然而,我面临的问题是使用定理1中给出的递归公式计算alpha时的舍入。显示函数定义如下:
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;
}
}
我的输出是:
.4344 2622 9508 1967 3732 7807 5683 6291 4025 7835 3881 8359 3750 0000 0000 0
问题输出是:
.4344 2622 9508 1967 2131 1475 4098 3606 5573 7704 9180 3278 6885 2459 0163 9
正如您所看到的,直到第16位才是正确的。所以我的问题是,在这种特殊情况下执行计算时如何防止截断数字?有什么想法吗?
答案 0 :(得分:4)
问题是double
没有无限的精度,而是只能管理大约16个十进制数字。因为输入double
中基本缺乏信息,所以你遇到麻烦(有趣,那个!)。
你需要找到一种解决问题的方法,当你从中得到更多的数字时,这个问题会越来越接近答案。这意味着你需要更多地思考定理3,并且还要根据有理数而不是浮点来编写代码。
答案 1 :(得分:2)
使用像gmp这样的bignum库。只有这么多信息可以打包成双人。
答案 2 :(得分:2)
我认为你想要一个任意精度库
像gnu MP bignum之类的东西,虽然其他风格是available