階乘問題

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 intlong 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)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容