CPU/编程语言使用哪些求幂算法?
我一直在学习更快的求幂算法(k元、滑动门等),想知道哪些算法在CPU/编程语言中使用?(我不清楚这是在CPU中还是通过编译器发生的) 就为了踢球,哪一个最快CPU/编程语言使用哪些求幂算法?,c,algorithm,math,compiler-construction,cryptography,C,Algorithm,Math,Compiler Construction,Cryptography,我一直在学习更快的求幂算法(k元、滑动门等),想知道哪些算法在CPU/编程语言中使用?(我不清楚这是在CPU中还是通过编译器发生的) 就为了踢球,哪一个最快 关于宽泛性的编辑:它是故意宽泛的,因为我知道有很多不同的技术可以做到这一点。选中的答案正是我想要的。我想您感兴趣的是HLL标准数学库中的求幂函数的实现,特别是C/C++。这些函数包括函数exp(),exp2(),exp10(),和pow(),以及单精度对应的expf(),exp2f(),exp10f(),和powf() 您提到的求幂方法(如
关于宽泛性的编辑:它是故意宽泛的,因为我知道有很多不同的技术可以做到这一点。选中的答案正是我想要的。我想您感兴趣的是HLL标准数学库中的求幂函数的实现,特别是C/C++。这些函数包括函数
exp()
,exp2()
,exp10()
,和pow()
,以及单精度对应的expf()
,exp2f()
,exp10f()
,和powf()
您提到的求幂方法(如k进制、滑动窗口)通常用于加密算法,如基于求幂的RSA。它们通常不用于通过math.h
或cmath
提供的求幂函数。标准数学函数(如exp()
的实现细节有所不同,但通用方案遵循三步流程:
log(0.0)
,或特殊的浮点操作数,如NaN(不是数字)
下面的expf(float)
的C99代码以示例性的方式显示了具体示例的这些步骤。参数a
首先被拆分,使得exp(a)
=er*2i,其中i
是一个整数,r
位于[log(sqrt(0.5)、log(sqrt(2.0)],主要近似区间。在第二步中,我们现在用多项式近似er。这种近似可以根据各种设计标准设计,如最小化绝对或相对误差。多项式可以用各种方法评估,包括Horner方案和Estrin方案
下面的代码使用了一种非常常见的方法,即使用极小极大近似,该近似可将整个近似区间内的最大误差降至最低。计算此类近似的标准算法是Remez算法。通过Horner方案进行评估;使用fma可提高此评估的数值精度f()
此标准数学函数实现了所谓的融合乘法加法或FMA。它在加法过程中使用完整的乘积a*b
计算a*b+c
,并在末尾应用一个舍入。在大多数现代硬件上,如GPU、IBM Power CPU、最新的x86处理器(如Haswell)、最新的ARM处理器(作为可选扩展),它直接映射到硬件指令。在缺少此类指令的平台上,fmaf()
将映射到相当慢的仿真代码,在这种情况下,如果我们对性能感兴趣,我们就不想使用它
<最后的计算是2i的乘法运算,其中C和C++提供函数<代码> LDEXP()<代码>。库代码one在这里通常使用特定于机器的习惯用法,它利用IEEE-754二进制算法进行float
。最后,代码清除溢出和下溢的情况
x86处理器内部的x87 FPU有一条指令F2XM1
,在[-1,1]上计算2x-1。这可用于exp()
和exp2()计算的第二步
。有一条指令FSCALE
,用于在第三步中乘以2i。实现F2XM1
本身的一种常见方法是使用有理或多项式近似值的微码。请注意,现在维护的x87 FPU主要用于传统支持。在现代x86平台上,库通常使用基于SSE的纯软件实现和如下所示的算法类似。一些结合了小表格和多项式近似
pow(x,y)
在概念上可以实现为exp(y*log(x))
,但当x
接近单位且y
的幅度较大时,这会导致严重的精度损失,并且C/C++标准中规定的许多特殊情况处理不当。解决精度问题的一种方法是计算log(x)
和产品y*log(x))
以某种形式的扩展精度。详细信息将填充一个完整、冗长的单独答案,我手头没有代码来演示。在各种C/C++数学库中,pow(double,int)
和powf(float,int)
由一个应用“平方和乘法”的单独代码路径计算对整数指数的二进制表示进行逐位扫描的方法
#include/*导入fmaf()、ldexpf()、无穷大*/
/*与rintf()类似,但-0.0f->+0.0f和| a |必须小于2**22*/
快速浮动和脏浮动(浮动a)
{
常量浮动cvt_magic=0x1.800000p+23f;
返回(a+cvt_魔法)-cvt_魔法;
}
/*间隔[log(sqrt(0.5)),log(sqrt(2.0))]上的近似exp(a)*/
浮点表达式多边形(浮点a)
{
浮子r;
r=0x1.694000p-10f;//1.37805939e-3
r=fmaf(r,a,0x1.125edcp-07f);/8.37312452e-3
r=fmaf(r,a,0x1.555b5ap-05f);/4.16695364e-2
r=fmaf(r,a,0x1.555450p-03f);//1.66664720e-1
r=fmaf(r,a,0x1.fffff6p-02f);/4.99999851e-1
r=fmaf(r,a,0x1.000000p+00f);//1.00000000e+0
r=