无符号长整型 pow 函数

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 ints:

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;
}

但是这个第二个版本似乎不起作用:
unsigned long long int x;
x = ipow( 2, 35 );
printf( "%llu\n", x );

这将输出0。

我的unsigned long long int实现有什么问题?

2个回答

7

您的 base 变量太小了。将其改为 unsigned long long int,像其他变量一样,因为它保存的数字大于 2^32


2

C标准的6.5p4节:

一些运算符(一元运算符~和二元运算符<<、>>、&、^和|,统称为位运算符)需要具有整数类型的操作数。这些运算符产生的值取决于整数的内部表示,并且对于带符号类型具有实现定义和未定义的方面。

C标准的6.5p5节:

如果在表达式求值过程中发生异常情况(即结果在其类型的可表示值范围之外或不是数学上定义的),则行为是未定义的。

如果之前在代码中使用int看起来是个好主意的话,那么现在就不应该了。这两个部分都表明你的代码不够可移植。


代码的哪一部分违反了标准中引用的部分? - Michał Trybus
@MichałTrybus 嗯,6.5p5是你回答背后的逻辑。 - autistic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接