0

この単純なコードを作成して、1005までのすべての正の整数の4乗を生成します。これは、整数215までしか正常に機能しません。その後、誤った読み取り値が返されます。なぜそうなのか?

# include<stdio.h>

int main(void)
{
    int i;
    unsigned long long int j;

    for (i = 1; i <= 1005; i++){
        j = i*i*i*i;
        printf("%i.........%llu\n",i,j);

    }

    return 0;

}
4

2 に答える 2

6

この小さな変更を加えることで修正できます。

unsigned long long i;

問題は、行j = i*i*i*i;で、右側intがに割り当てられる前に計算されていることjです。このため、i^4整数の制限を超えると、基本的に最初に負になり始め、上位ビットがクリップされると循環を開始します。に負の数を割り当てるとjj符号なしなので、はに-iなりますmax - i。これが巨大な数の由来です。printfまた、フォーマット指定子をからに%i変更する必要があります。%llui

以下を実行してこれを修正することもできます

j = (unsigned long long)i*i*i*i;

jこれは基本的に、乗算を実行する前に、のタイプにキャストを強制します。

健全性チェック- 215 ^4=2136750625は、上限signed intの2,147,483,647に非常に近い値です。

于 2013-01-12T08:43:40.730 に答える
4

i*iを生成しintます。と も同様i*i*iですi*i*i*i。215 は、4 乗が 32 ビットに収まる最大の正の整数ですint

それを超えると、結果は通常切り捨てられます (通常、厳密に言えば、未定義の動作のケースがあるためです。符号付き整数のオーバーフローは、C 標準に従って UB になります)。

にキャストiunsigned long longたり、 として定義したりすることunsigned long longができるため、乗算は 64 ビットです。

    j = (unsigned long long)i*i*i*i;
于 2013-01-12T08:48:01.060 に答える