user-0 提问: 新手小白，找个大佬带带我

回复:
user: user-0
content: 好的好的，谢谢大家

user: user-1
content: 引用 7 楼 qq_45773596 的回复:[quote=引用 6 楼 自信男孩的回复:][quote=引用 2 楼 真的小白啊 的回复:]这样是不是就明白一些  int main() {     /*      * 1!+2!+3!+…+19!+20!      *      * 1*1 + 2*1 + 3*2*1 + 4*3*2*1 +      * */          //一个数用来保存每一项阶乘     double last = 1;     //一个数用来求和     double sum = 0;     //从1到20     for (int i = 1; i <= 20; i++)     {         last *= i;  //i=1 => 1*(1)    i=2 => 2*(1*1)    i=3 => 3*(2*1*1)    i=4 => 4*(3*2*1*1)         sum += last;    //累加起来     }     //打印结果     printf("sum = %lf\n", sum);     return 0; }  测试了一下，你的程序输出结果是： sum = 2561327494111820288.000000 个人感觉这个结果是不对的，因为这个结果应该是一个奇数，而不是偶数；  last和sum定义为unsigned long long后得到的结果是 sum = 2561327494111820313  将last和sum定义为long double后就没问题了，得到了： sum = 2561327494111820313.000000  另外，对于long double的输出建议用%.0Lf格式输出，因为阶层和不会得到一个浮点数（实数），应该得到一个整数才对；  [/quote] 我晕了，哪一个方法是对的呀[/quote] 跟方法没关系的。是类型运算出现的问题。这位朋友给你推荐的算法没问题的，而是变量的类型有点问题，改成long double（自测）就可以。 当然，用unsigned long long也是没问题的。  这也是楼主需要注意的，需要考虑类型的取值范围，考虑是否会溢出以及类型的运算等等

user: user-2
content: 引用 6 楼 自信男孩 的回复:[quote=引用 2 楼 真的小白啊 的回复:]这样是不是就明白一些  int main() {     /*      * 1!+2!+3!+…+19!+20!      *      * 1*1 + 2*1 + 3*2*1 + 4*3*2*1 +      * */          //一个数用来保存每一项阶乘     double last = 1;     //一个数用来求和     double sum = 0;     //从1到20     for (int i = 1; i <= 20; i++)     {         last *= i;  //i=1 => 1*(1)    i=2 => 2*(1*1)    i=3 => 3*(2*1*1)    i=4 => 4*(3*2*1*1)         sum += last;    //累加起来     }     //打印结果     printf("sum = %lf\n", sum);     return 0; }  测试了一下，你的程序输出结果是： sum = 2561327494111820288.000000 个人感觉这个结果是不对的，因为这个结果应该是一个奇数，而不是偶数；  last和sum定义为unsigned long long后得到的结果是 sum = 2561327494111820313  将last和sum定义为long double后就没问题了，得到了： sum = 2561327494111820313.000000  另外，对于long double的输出建议用%.0Lf格式输出，因为阶层和不会得到一个浮点数（实数），应该得到一个整数才对；  [/quote]  感谢对小白的指正，在变量类型方面我还存在许多不足

user: user-0
content: 引用 6 楼 自信男孩的回复:[quote=引用 2 楼 真的小白啊 的回复:]这样是不是就明白一些  int main() {     /*      * 1!+2!+3!+…+19!+20!      *      * 1*1 + 2*1 + 3*2*1 + 4*3*2*1 +      * */          //一个数用来保存每一项阶乘     double last = 1;     //一个数用来求和     double sum = 0;     //从1到20     for (int i = 1; i <= 20; i++)     {         last *= i;  //i=1 => 1*(1)    i=2 => 2*(1*1)    i=3 => 3*(2*1*1)    i=4 => 4*(3*2*1*1)         sum += last;    //累加起来     }     //打印结果     printf("sum = %lf\n", sum);     return 0; }  测试了一下，你的程序输出结果是： sum = 2561327494111820288.000000 个人感觉这个结果是不对的，因为这个结果应该是一个奇数，而不是偶数；  last和sum定义为unsigned long long后得到的结果是 sum = 2561327494111820313  将last和sum定义为long double后就没问题了，得到了： sum = 2561327494111820313.000000  另外，对于long double的输出建议用%.0Lf格式输出，因为阶层和不会得到一个浮点数（实数），应该得到一个整数才对；  [/quote] 我晕了，哪一个方法是对的呀

user: user-1
content: 引用 2 楼 真的小白啊 的回复:这样是不是就明白一些  int main() {     /*      * 1!+2!+3!+…+19!+20!      *      * 1*1 + 2*1 + 3*2*1 + 4*3*2*1 +      * */          //一个数用来保存每一项阶乘     double last = 1;     //一个数用来求和     double sum = 0;     //从1到20     for (int i = 1; i <= 20; i++)     {         last *= i;  //i=1 => 1*(1)    i=2 => 2*(1*1)    i=3 => 3*(2*1*1)    i=4 => 4*(3*2*1*1)         sum += last;    //累加起来     }     //打印结果     printf("sum = %lf\n", sum);     return 0; }  测试了一下，你的程序输出结果是： sum = 2561327494111820288.000000 个人感觉这个结果是不对的，因为这个结果应该是一个奇数，而不是偶数；  last和sum定义为unsigned long long后得到的结果是 sum = 2561327494111820313  将last和sum定义为long double后就没问题了，得到了： sum = 2561327494111820313.000000  另外，对于long double的输出建议用%.0Lf格式输出，因为阶层和不会得到一个浮点数（实数），应该得到一个整数才对；

user: user-3
content: 引用 3 楼 qq_45773596 的回复:刚才试了。谢谢哈 不过第四行和倒数第二行代码，我不太理解 在做ACM题时，经常都会遇到一些比较大的整数。而常用的内置整数类型常常显得太小了:其中long 和 int 范围 是[-2^31,2^31)，即-2147483648~2147483647。而unsigned范围是[0,2^32)，即0~4294967295。也就是说， 常规的32位整数只能够处理40亿以下的数。 那遇到比40亿要大的数怎么办呢？这时就要用到C++的64位扩展了。不同的编译器对64位整数的扩展 有所不同。VC6.0的64位整数分别叫做__int64与unsigned __int64，其范围分别是[-2^63, 2^63)与[0,2^64)，即-9223372036854775808~9223372036854775807与0~18446744073709551615(约1800亿亿)。对64位整数的运算与32位整数基本相同，都支持四则运算与位运算等。

user: user-0
content: 引用 2 楼 真的小白啊的回复:这样是不是就明白一些  int main() {     /*      * 1!+2!+3!+…+19!+20!      *      * 1*1 + 2*1 + 3*2*1 + 4*3*2*1 +      * */          //一个数用来保存每一项阶乘     double last = 1;     //一个数用来求和     double sum = 0;     //从1到20     for (int i = 1; i <= 20; i++)     {         last *= i;  //i=1 => 1*(1)    i=2 => 2*(1*1)    i=3 => 3*(2*1*1)    i=4 => 4*(3*2*1*1)         sum += last;    //累加起来     }     //打印结果     printf("sum = %lf\n", sum);     return 0; }  懂了，谢谢哈

user: user-0
content: 刚才试了。谢谢哈 不过第四行和倒数第二行代码，我不太理解

user: user-2
content: 这样是不是就明白一些  int main() {     /*      * 1!+2!+3!+…+19!+20!      *      * 1*1 + 2*1 + 3*2*1 + 4*3*2*1 +      * */          //一个数用来保存每一项阶乘     double last = 1;     //一个数用来求和     double sum = 0;     //从1到20     for (int i = 1; i <= 20; i++)     {         last *= i;  //i=1 => 1*(1)    i=2 => 2*(1*1)    i=3 => 3*(2*1*1)    i=4 => 4*(3*2*1*1)         sum += last;    //累加起来     }     //打印结果     printf("sum = %lf\n", sum);     return 0; }

user: user-3
content: 20!很大了，装不下了，供参考：#include<stdio.h>  int main() {     int i;     __int64 s=0,tmp=1;     for(i=1;i<=20;i++)     {        tmp *= i;        s+=tmp;     }     printf("%I64d\n",s);          return 0; }

user: user-4
content: 过来学习，谢谢分享