这里就是在反复强调同一个观点。在C语言中,计算整数次幂的一种典型(且较快)方法如下:
int64_t ipow(int64_t base, int exp){
int64_t result = 1;
while(exp){
if(exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
return result;
}
但是我需要一个在编译时计算整数幂的函数,所以我继续使用constexpr实现了一个递归函数:
constexpr int64_t ipow_(int base, int exp){
return exp > 1 ? ipow_(base, (exp>>1) + (exp&1)) * ipow_(base, exp>>1) : base;
}
constexpr int64_t ipow(int base, int exp){
return exp < 1 ? 1 : ipow_(base, exp);
}
第二个函数的作用只是以可预测的方式处理小于1的指数。在这种情况下传递exp<0
是一个错误。
递归版本要慢4倍
我生成了一个由10E6个随机值为基数和指数组成的向量,并对向量中的两个算法进行计时(之前进行了一次非计时运行以尝试消除任何缓存效应)。没有优化的情况下,递归方法比循环方法快两倍。但是使用-O3(GCC)时,循环方法比递归方法快4倍。
我想问你们的问题是:有人能想出一个更快的ipow()函数,可以处理基数和指数为0的情况,并且可以用作constexpr
吗?
(免责声明:我不需要更快的ipow,我只是想看看这里聪明的人能想出什么)。
constexpr
函数也可以在运行时进行评估。期望的优化是针对运行时评估的情况。如果递归方法在运行时与循环方法相比速度相当快,则可以在编译时和运行时都使用递归方法,而无需为运行时版本单独定义。请参见@hivert的答案。 - Emily L.ipow
函数。;) - Caseyconstexpr
函数中大幅扩展了您可以执行的操作:详见N3652。您的第一个实现在C++1y中是一个有效的constexpr
函数。 - Caseyconstexpr
关键字,原始函数即可在编译时完美运行。 - Casey