纯C实现sqrt,cos,sin,atan2 您所在的位置:网站首页 atan2函数c语言 纯C实现sqrt,cos,sin,atan2

纯C实现sqrt,cos,sin,atan2

2023-11-01 22:01| 来源: 网络整理| 查看: 265

某个项目的需求不允许使用标准库函数,算法中有sqrt,cos,sin,atan2这些函数必须要自己写。

一开始的想法就是cos,sin,atan2都可以使用泰勒级数,sqrt可以使用牛顿法。

然后。。。上网找资料。。。

首先是SQRT,这位仁兄基本思路和我一样,但是他在最后提供的这段代码的确很神奇。列在下面。

float Sqrt(float x) { float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f375a86 - (i >> 1); x = *(float*)&i; x = x*(1.5f - xhalf*x*x); x = x*(1.5f - xhalf*x*x); x = x*(1.5f - xhalf*x*x); return 1 / x; }

而后是COS和SIN,也是用泰勒级数,但是程序有点问题,我做了小小修正:

float Sin(float x) { int sign = 1; int itemCnt = 4; int k = 0; float result = 0.0f; float tx = 0.0f; int factorial = 1; if(x < 0) { x = -x; sign *= -1; } while(x >= SL_2PI) { x -= SL_2PI; } if(x > SL_PI) { x -= SL_PI; sign *= -1; } if(x > SL_PI_DIV_2) { x = SL_PI - x; } tx = x; for (k = 0; k < itemCnt; k ++) { if(k%2 == 0) { result += (tx / factorial); } else { result -= (tx / factorial); } tx *= (x * x); factorial *= (2*(k+1)); factorial *= (2*(k+1) + 1); } if (1 == sign) return result; else return -result; }

atan2有点麻烦,因为sin和cos的级数收敛很快(分母为(2n+1)!和(2n)!),而atan不一样,分母为2n+1。WIKI上面有一个更加有效率的公式:

但是感觉收敛效果仍旧一般,所以最终选择了积分式,代码如下:

float Atan2(float y, float x, int infNum) { int i; float z = y / x, sum = 0.0f,temp; float del = z / infNum; for (i = 0; i < infNum;i++) { z = i*del; temp = 1 / (z*z + 1) * del; sum += temp; } if (x>0) { return sum; } else if (y >= 0 && x < 0) { return sum + PI; } else if (y < 0 && x < 0) { return sum - PI; } else if (y > 0 && x == 0) { return PI / 2; } else if (y < 0 && x == 0) { return -1 * PI / 2; } else { return 0; } }

后面一大段if else条件判断是因为atan2和atan的区别:

 

这个方法虽然误差已经很小了,至少不影响我计算方向场,但是应该还有更好的。至少我在stackoverflow里面看到的是如此。比如有如此开源代码,苹果的。

 

从现在的这类需求看出,很可能要慢慢琢磨怎么样去实现其他的函数。 

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有