正文

[033] 阶乘->数据的范围2006-03-12 16:10:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/wentao/10938.html

分享到:

<谭> P120

6.4 求 1!+2!+3!+...+20!

#include <stdio.h>
int main()
{
    int t = 1; /* t表示各项值 */
    int s = 0; /* s表示各项和 */
    int i;
    for(i = 1; i <= 20; i++)
    {
        t = t * i;
        s = s + t;
    }
    printf("1!+2!+3!+...+20!=%d\n", s);
    return 0;
}

运行结果:
================================
1!+2!+3!+...+20!=268040729
================================

那么这个结果是否正确呢, 首先将各项输出看一下


#include <stdio.h>
int main()
{
    int t = 1; /* t表示各项值 */
    int s = 0; /* s表示各项和 */
    int i;
    for(i = 1; i <= 20; i++)
    {
        t = t * i;
        s = s + t;
        printf("%d!=%d\n", i, t);  /* 输出各项 */
    }
    printf("1!+2!+3!+...+20!=%d\n", s);
    return 0;
}

TC下运行结果:
================================
1!=1
2!=2
3!=6
4!=24
5!=120
6!=720
7!=5040
8!=-25216
9!=-30336
10!=24320
11!=5376
12!=-1024
13!=-13312
14!=10240
15!=22528
16!=-32768
17!=-32768
18!=0
19!=0
20!=0
1!+2!+3!+...+20!=-1511
================================

显然到了8!出错了, 原因在于 int 型数据范围是 -32768~32767, 也不能用long型, 因为long 型数据范围为-2147483648~2147483647 ,无法容纳求得的结果。

VC++6.0下运行结果:
================================
1!=1
2!=2
3!=6
4!=24
5!=120
6!=720
7!=5040
8!=40320
9!=362880
10!=3628800
11!=39916800
12!=479001600
13!=1932053504
14!=1278945280
15!=2004310016
16!=2004189184
17!=-288522240
18!=-898433024
19!=109641728
20!=-2102132736
1!+2!+3!+...+20!=268040729
================================

仍然是错的,从17!开始, 对于32位机, int 取值范围为 -231~231-1

修改如下:

#include <stdio.h>
int main()
{
    float t = 1; /* t表示各项值 */
    float s = 0; /* s表示各项和 */
    int i;
    for(i = 1; i <= 20; i++)
    {
        t = t * i;
        s = s + t;
        printf("%d!=%-20.0f\n", i, t);  /* 输出各项 */
    }
    printf("1!+2!+3!+...+20!=%20.0f\n", s);
    return 0;
}

TC,VC运行结果均为:
=========================================================
1!=1
2!=2
3!=6
4!=24
5!=120
6!=720
7!=5040
8!=40320
9!=362880
10!=3628800
11!=39916800
12!=479001600
13!=6227020800
14!=87178289152
15!=1307674279936
16!=20922788478976
17!=355687414628352
18!=6402373530419200
19!=121645096004222980
20!=2432902023163674600
1!+2!+3!+...+20!= 2561327455189073900
=========================================================

当然也可以用指数形式(%e)输出.

当数据较大时,要注意所定义数据类型是否够数据位宽, 否则将会溢出。还要注意编译的机器及环境。


[更新] 2006.11.19  [071] 递归法求阶乘 。

######################################更正########################################
[2006.12.16]
经网友指点(见评论),发现上面这个程序仍然是错误的,13!还是正确的,而14!就出错了,因为13!后面已经有两个0了,而14!后却没有了,显然是错的,用Windows自带的计算器检验一下,14!=87178291200,看来用float来做的话精度还是有问题。

显然,对于比较大的数阶乘仅通过数据的精度是解决不了的。网上搜了一下,原来对于大数的阶乘涉及到一些算法,考完试后再好好研究一下,待续……

阅读(3920) | 评论(6)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册