1

64 ビット整数を操作する必要があります。演習として (および要件として) 36 を 12 乗した結果を取得しようとしています。

VS2008 コンパイラで 64 ビット整数に unsigned long long を使用しました。以下のコードを作成しましたが、Power 関数の再帰バージョンでは正しい結果が生成されるのに、for ループ バージョンでは誤った結果が生成されるのはなぜですか?

参考までに: 36 を 12 に上げると、4738381338321616896 になります。

template< typename _T1, typename _T2 >
_T1 Power( _T1 p_base, _T2 p_power )
{
    /*
    // This produces 0?!!
    if( p_power == 0 ) return 1;
    for( _T2 i = 1; i < p_power; ++i )
    {
        p_base *= p_base;
    }

    return p_base;
    */

    // This produces correct result.
    if( p_power == 0 ) return 1;
    if( p_power == 1 ) return p_base;

    return p_base * Power( p_base, p_power - 1 );
}

void main( int argc, char * argv[] )
{
    unsigned long long charsetSize = 36LL;
    printf( "Maximum Keys: %llu\n\n", Power( charsetSize, 12 ) );

    system( "pause" );
}
4

3 に答える 3

5

各反復で結果を二乗しています。次のようになります。

_T1 result = 1;
for( _T2 i = 0; i < p_power; ++i )
{
    result *= p_base;
}

このようにループを記述した場合、p_power == 0チェックは不要なので注意してください。

于 2010-11-11T04:25:15.030 に答える
1

これは、各乗算の結果を p_base に格納しているためです。これにより、変数がオーバーフローする可能性があります。

p_base の入力値と「作業」変数を別々に保存する必要があります。for ループのロジックでは、2 の 4 乗は 65536 です。

于 2010-11-11T04:26:01.613 に答える
1

p_base *= p_base;

これは正しくありません。結果は各反復後に二乗されます

修正

_T1 pow = 1LL;
for( _T2 i = 1; i <= p_power; ++i )
{
    pow *= p_base;
}
return pow;
于 2010-11-11T04:27:30.273 に答える