去年开始接触WebAssembly,是一种可以在浏览器中运行的汇编语言,据称运行速度会很快,就想试试。但遇到一个问题,就是WebAssembly指令只提供了基础的加减乘除算法,连三角函数等都没有,稍微复杂的计算都实现不了,想进行一些复杂一些的计算都要自己写代码。
三角函数,虽然可以使用泰勒级数来计算,但实际计算量比较大而且收敛比较慢,其实直接这样计算效率比较低,但查不到改进的算法,也不知一些编程语言中的对应函数的底层计算代码,很是头疼。不过查到了一种使用迭代计算三角函数的方法,也就是CORDIC(Coordinate Rotation Digital Computer,坐标旋转数字计算)算法,可以只通过加减和移位就能计算任意角度的三角函数值,精度可以满足于工程需要,因此就非常感兴趣。
按网上资料,CORDIC算法是J.D.Volder1于1959年首次提出,首先用于导航系统,可以用来实现三角函数、双曲线、指数、对数的计算,J. Walther在1974年用它研究了一种能计算出多种超越函数的统一算法。其基本原理为:
初始向量(X0,Y0)旋转θ角度之后得到向量(X1,Y1),此向量有如下关系:
X1=X0*cos(θ)-Y0*sin(θ)=cos(θ)(X0-Y0*tan(θ))
Y1=Y0*cos(θ)+X0*sin(θ)=cos(θ)(Y0+X0*tan(θ))
可以从一个起始角度开始,经过一系列旋转,达到需要的角度,为了计算方便,一般会选择一些特殊角度,比如设置第i次旋转角度为δ=arctan(2^(-i))。
以sin/cos计算为例,可利用正/余弦的和角公式迭代进行:
cos(a+b) = cos(a)cos(b) – sin(a)sin(b) = cos(a) [cos(b) – tan(a)sin(b)]
sin(a+b) = sin(a)cos(b) + cos(a)sin(b) = cos(a) [tan(a)cos(b) +sin(b)]
取a=arctan(2^-k), 即tan(a)=2^-k, 则cos(b) – tan(a)sin(b)。迭代公式为: