c语言实现的sin cos查找表_CORDIC三角函数的JS实现

去年开始接触WebAssembly,是一种可以在浏览器中运行的汇编语言,据称运行速度会很快,就想试试。但遇到一个问题,就是WebAssembly指令只提供了基础的加减乘除算法,连三角函数等都没有,稍微复杂的计算都实现不了,想进行一些复杂一些的计算都要自己写代码。

三角函数,虽然可以使用泰勒级数来计算,但实际计算量比较大而且收敛比较慢,其实直接这样计算效率比较低,但查不到改进的算法,也不知一些编程语言中的对应函数的底层计算代码,很是头疼。不过查到了一种使用迭代计算三角函数的方法,也就是CORDIC(Coordinate Rotation Digital Computer,坐标旋转数字计算)算法,可以只通过加减和移位就能计算任意角度的三角函数值,精度可以满足于工程需要,因此就非常感兴趣。

按网上资料,CORDIC算法是J.D.Volder1于1959年首次提出,首先用于导航系统,可以用来实现三角函数、双曲线、指数、对数的计算,J. Walther在1974年用它研究了一种能计算出多种超越函数的统一算法。其基本原理为:

b6742d0be8fddb2f44ef0732265f3b44.png

初始向量(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)。迭代公式为:

63fa48e1266331b9a78304dc0fc6f2bf.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Xilinx提供了CORDIC IP核,可以用于实现三角函数计算。CORDIC(Coordinate Rotation Digital Computer)是一种通过旋转坐标轴来计算三角函数的算法,它具有高精度、低功耗、低面积等优点,在数字信号处理、通信、图像处理等领域得到广泛应用。 以下是实现正弦函数计算的示例代码: ```verilog `timescale 1ns / 1ps module cordic_sin ( input signed [31:0] angle, output reg signed [31:0] sin_out ); wire signed [31:0] x, y, z; reg signed [31:0] x_buf, y_buf, z_buf; reg [31:0] i; CORDIC #( .DATA_WIDTH(32), .MODE(1), // Mode 1: Compute sin and cos .ITERATIONS(16), // Number of iterations .ANGLE_PRECISION(32), // Angle precision .PIPELINE_STAGE(0) // Pipeline stage ) cordic_inst ( .x(x), .y(y), .z(z) ); // Initial values assign x = angle; assign y = 0; assign z = 0; always @ (posedge cordic_inst.clk) begin if (cordic_inst.done) begin sin_out <= y_buf; x_buf <= x; y_buf <= y; z_buf <= z; i <= 0; end else begin // Shift x, y, z for next iteration x_buf <= x; y_buf <= y; z_buf <= z; x <= cordic_inst.x_out >> i; y <= cordic_inst.y_out >> i; z <= cordic_inst.z_out >> i; i <= i + 1; end end endmodule ``` 在上面的代码中,我们使用CORDIC IP核计算输入角度的正弦值。输入角度为一个有符号的32位整数,输出正弦值也是一个有符号的32位整数。我们使用MODE 1来计算正弦和余弦,ITERATIONS为16,ANGLE_PRECISION为32(示输入角度的精度为32位),PIPELINE_STAGE为0(示不使用流水线)。 我们将输入角度直接赋值给x,y和z的初始值都为0。每次CORDIC IP核完成一次计算后,我们将得到下一次计算的x、y和z值,同时将当前计算得到的y值存储在sin_out寄存器中。 需要注意的是,CORDIC IP核是一个带有时钟的模块,因此我们需要在时钟上升沿时检查计算是否完成。如果计算完成,我们将存储下一次计算所需的x、y和z值,并将i重置为0,以便进行下一轮迭代。 值得注意的是,CORDIC IP核支持流水线操作,可以在可接受的延迟范围内提高性能。如果您需要更快的计算速度,可以尝试调整PIPELINE_STAGE参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值