6

整数で動作する次の累乗関数があり、正常に動作します。

int ipow( int base, int exp )
{
    int result = 1;
    while( exp )
    {
        if ( exp & 1 )
        {
            result *= base;
        }
        exp >>= 1;
        base *= base;
    }
    return result;
}

ここで、exp > 32 を許可するバージョンが必要です。したがって、unsigned long long int を使用します。

unsigned long long int ipow( int base, int exp )
{
    unsigned long long int result = 1ULL;
    while( exp )
    {
        if ( exp & 1 )
        {
            result *= (unsigned long long int)base;
        }
        exp >>= 1;
        base *= base;
    }
    return result;
}

しかし、この 2 番目のバージョンは機能していないようです。

unsigned long long int x;
x = ipow( 2, 35 );
printf( "%llu\n", x );

これは 0 を出力します。

unsigned long long int 実装の問題は何ですか?

4

2 に答える 2

7

変数baseが小さすぎます。unsigned long long intより大きい数値を保持しているため、他のものと同様に に変更し2^32ます。

于 2013-03-05T13:30:23.593 に答える
2

C 標準のセクション 6.5p4:

一部の演算子 (単項演算子 ~ と、2 項演算子 <<、>>、&、^、および | をまとめてビット演算子と呼ぶ) は、整数型のオペランドを持つ必要があります。これらの演算子は、整数の内部表現に依存する値を生成し、符号付き型の実装定義および未定義の側面を持ちます。

C 標準のセクション 6.5p5:

式の評価中に例外的な条件が発生した場合 (つまり、結果が数学的に定義されていないか、その型の表現可能な値の範囲内にない場合)、動作は未定義です。

int以前はこのコードで使用するのが良いと思われていた場合でも、今はそうすべきではありません。これらのセクションは両方とも、あなたのコードは可能な限り移植可能ではないと言っています。

于 2013-03-05T13:30:55.143 に答える