1、題目
image
2、代碼
#include <bits/stdc++.h>
using namespace 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;
return 0;
}
這個(gè)代碼只得了 60 分,Why?
問題還是出現(xiàn)在數(shù)據(jù)類型上,int可以表示的最大的數(shù)為 2147483647,而20的階乘是** 2192834560**,已經(jīng)超出了 int 的范圍,所以應(yīng)該修改階乘函數(shù)的返回值類型。
試著在 OJ 系統(tǒng)上將 int 換成了 long,則AC通過。
在本機(jī)上運(yùn)行時(shí),發(fā)現(xiàn)返回值是負(fù)數(shù),有點(diǎn)迷惑,寫了下面的代碼來分析。
3、具體分析
#include<bits/stdc++.h>
using namespace std;
long f(int n)
{
if(n==0)
{
return1;
}
return n*f(n-1);
}
int main()
{
int n;
printf("int 可以表示的最大的數(shù)為\n%d\n", INT_MAX);
printf("long 可以表示的最大的數(shù)為\n%ld\n", LONG_MAX);
printf("long long 可以表示的最大的數(shù)為\n%lld\n", LLONG_MAX);
printf("unsigned long long 可以表示的最大的數(shù)為\n%llu\n", ULLONG_MAX);
printf("你要計(jì)算前幾個(gè)數(shù)?(q to quit):\n");
while(scanf("%d",&n)==1)
{
if(n <0)
printf("無效的數(shù)字\n");
else
{
printf("前%d 個(gè)數(shù)的階乘是\n%lld\n", n, f(n));
}
}
return0;
}
以上程序的運(yùn)行輸出如下:
1. int可以表示的最大的數(shù)為
2. 2147483647
3. long可以表示的最大的數(shù)為
4. 2147483647
5. longlong可以表示的最大的數(shù)為
6. 9223372036854775807
7. unsignedlonglong可以表示的最大的數(shù)為
8. 18446744073709551615
9. 你要計(jì)算前幾個(gè)數(shù)?(q to quit):
10. 20
11. 前20個(gè)數(shù)的階乘是
12. 2192834560
4、問題分析
也就是說,我本機(jī)的編譯器中,int 和 long 的數(shù)據(jù)范圍是一樣的,而在我使用的 oj 系統(tǒng)上是不一樣的,因此此處保險(xiǎn)的策略是將階乘函數(shù)的返回值寫成 long long。****下面進(jìn)行了一點(diǎn)點(diǎn)深入的分析。
** long 類型的長度**
數(shù)據(jù)類型的字節(jié)數(shù)應(yīng)該是由CPU決定的。
對(duì)于C語言的int,無論是32位編譯器還是64位,都是4個(gè)字節(jié)。
long類型在32位編譯器是4個(gè)字節(jié),64位是8個(gè)字節(jié)。
宏LONG_MAX和LLONG_MAX均存在于頭文件limits.h中,分別表示long int 和long long int類型的最大值。
Dev C++ 的安裝目錄中,也能找到 limits.h,內(nèi)容如下:
#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 位編譯器。
5\數(shù)據(jù)類型范圍速查表
char -128 ~ +127 (1 Byte)
short -32767 ~ + 32768 (2 Bytes) **3*10^4**
unsigned short 0 ~ 65536 (2 Bytes) ** 6*10^4**
int -2147483648 ~ +2147483647 (4 Bytes) ** 2*10^9**
unsigned int 0 ~ 4294967295 (4 Bytes) **4*10^9**
long == int
long long -9223372036854775808 ~ +9223372036854775807 (8 Bytes) ** 9*10^18**
double **1.7 * 10^308 ** (8 Bytes)