我正在阅读 如何自己编写幂函数? dan04给出的答案引起了我的注意,主要是因为我不确定fortran给出的答案,但我接受了它并实现了这个:
#include <iostream>
using namespace std;
float pow(float base, float ex){
// power of 0
if (ex == 0){
return 1;
// negative exponenet
}else if( ex < 0){
return 1 / pow(base, -ex);
// even exponenet
}else if ((int)ex % 2 == 0){
float half_pow = pow(base, ex/2);
return half_pow * half_pow;
//integer exponenet
}else{
return base * pow(base, ex - 1);
}
}
int main(){
for (int ii = 0; ii< 10; ii++){\
cout << "pow(" << ii << ".5) = " << pow(ii, .5) << endl;
cout << "pow(" << ii << ",2) = " << pow(ii, 2) << endl;
cout << "pow(" << ii << ",3) = " << pow(ii, 3) << endl;
}
}
虽然我不确定我是否翻译正确,因为所有以 0.5 作为指数的调用都返回 0。在答案中它指出它可能需要基于 a^b = 2^(b * log2(a))
的 log2(x) ,但我我不确定把它放进去,因为我不确定把它放在哪里,或者我什至在考虑这个权利。
注意:我知道这可能是在数学库中定义的,但我不需要为几个函数增加整个数学库的所有额外费用。
编辑:有人知道小数指数的浮点实现吗? (我见过一个双重实现,但那是使用寄存器的技巧,我需要浮点,并且添加一个库只是为了做一个技巧我最好只包括数学库)
原文由 gardian06 发布,翻译遵循 CC BY-SA 4.0 许可协议
我在 这里 看过这篇论文,它描述了如何逼近双精度的指数函数。在维基百科上对单精度浮点表示进行了一些研究之后,我已经制定了等效算法。他们只实现了 exp 函数,所以我为日志找到了一个反函数,然后简单地做了
编译这个 gcc4.6.2 产生的 pow 函数几乎比标准库的实现(使用 O2 编译)快 4 倍。
注意:EXP 的代码几乎是从我阅读的论文中逐字复制的,LOG 函数是从 这里 复制的。
以下是相关代码:
您仍然可以在这里进行一些优化,或者这可能已经足够好了。这是一个粗略的近似值,但如果您对使用双重表示引入的错误感到满意,我想这将是令人满意的。