题目
代码
#include<bits/stdc++.h>
usingnamespace std;
int f(int n)
{
if(n<=0)
{
return 1;
}
return n*f(n-1);
}
int main()
{
int n;
cin>>n;
int m = f(n)%1007;
cout<< m<<endl;
return0;
}
这个代码只得了 60 分,Why?
问题还是出现在数据类型上,int可以表示的最大的数为 2147483647,而20的阶乘是 2192834560,已经超出了 int 的范围,所以应该修改阶乘函数的返回值类型。
试着在 OJ 系统上将 int 换成了 long,则AC通过。
在本机上运行时,发现返回值是负数,有点迷惑,写了下面的代码来分析。
代码
#include<bits/stdc++.h>
usingnamespace std;
long f(int n)
{
if(n==0)
{
return1;
}
return n*f(n-1);
}
int main()
{
int n;
printf("int 可以表示的最大的数为\n%d\n", INT_MAX);
printf("long 可以表示的最大的数为\n%ld\n", LONG_MAX);
printf("long long 可以表示的最大的数为\n%lld\n", LLONG_MAX);
printf("unsigned long long 可以表示的最大的数为\n%llu\n", ULLONG_MAX);
printf("你要计算前几个数?(q to quit):\n");
while(scanf("%d",&n)==1)
{
if(n <0)
printf("无效的数字\n");
else
{
printf("前%d 个数的阶乘是\n%lld\n", n, f(n));
}
}
return0;
}
以上程序的运行输出如下:
int可以表示的最大的数为
2147483647
long可以表示的最大的数为
2147483647
longlong可以表示的最大的数为
9223372036854775807
unsignedlonglong可以表示的最大的数为
18446744073709551615
你要计算前几个数?(q to quit):
20
前20个数的阶乘是
2192834560
+
问题分析
也就是说,我本机的编译器中,int 和 long 的数据范围是一样的,而在我使用的 oj 系统上是不一样的,因此此处保险的策略是将阶乘函数的返回值写成 long long。 下面进行了一点点深入的分析。long 类型的长度
数据类型的字节数应该是由CPU决定的。
对于C语言的int,无论是32位编译器还是64位,都是4个字节。long类型在32位编译器是4个字节,64位是8个字节。
宏LONG_MAX和LLONG_MAX均存在于头文件limits.h
中,分别表示long int
和long long int
类型的最大值。
Dev C++ 的安装目录中,也能找到 limits.h,内容如下:
#define PATH_MAX 260
#define CHAR_BIT 8
#define SCHAR_MIN (-128)
#define SCHAR_MAX 127
#define UCHAR_MAX 0xff
#define CHAR_MIN SCHAR_MIN
#define CHAR_MAX SCHAR_MAX
#define MB_LEN_MAX 5
#define SHRT_MIN (-32768)
#define SHRT_MAX 32767
#define USHRT_MAX 0xffffU
#define INT_MIN (-2147483647-1)
#define INT_MAX 2147483647
#define UINT_MAX 0xffffffffU
#define LONG_MIN (-2147483647L-1)
#define LONG_MAX 2147483647L
#define ULONG_MAX 0xffffffffUL
#define LLONG_MAX 9223372036854775807ll
#define LLONG_MIN (-9223372036854775807ll-1)
#define ULLONG_MAX 0xffffffffffffffffull
#define _I8_MIN (-127-1)
#define _I8_MAX 127
#define _UI8_MAX 0xffu
#define _I16_MIN (-32767-1)
#define _I16_MAX 32767
#define _UI16_MAX 0xffffu
#define _I32_MIN (-2147483647-1)
#define _I32_MAX 2147483647
#define _UI32_MAX 0xffffffffu
#if defined(__GNUC__)
#undef LONG_LONG_MAX
#define LONG_LONG_MAX 9223372036854775807ll
#undef LONG_LONG_MIN
#define LONG_LONG_MIN (-LONG_LONG_MAX-1)
#undef ULONG_LONG_MAX
#define ULONG_LONG_MAX (2ull* LONG_LONG_MAX +1ull)
#endif
#define _I64_MIN (-9223372036854775807ll-1)
#define _I64_MAX 9223372036854775807ll
#define _UI64_MAX 0xffffffffffffffffull
也就是说,Dev C++ 是 32 位编译器。
数据类型范围速查表
char -128 ~ +127 (1 Byte) short -32767 ~ + 32768 (2 Bytes) 3*10^4unsigned short 0 ~ 65536 (2 Bytes) 6*10^4int -2147483648 ~ +2147483647 (4 Bytes) 2*10^9unsigned int 0 ~ 4294967295 (4 Bytes) 4*10^9long == intlong long -9223372036854775808 ~ +9223372036854775807 (8 Bytes) 9*10^18double 1.7 * 10^308 (8 Bytes)