通过泰勒展开式计算反正弦函数

我们知道任何收敛的函数都可以通过泰勒公式展开,通过这个思路我们便可以方便的对一些没有解析表达式的函数求解反函数,泰勒展开的相关知识可以翻阅信号与系统相关书籍。在这里举例计算反正弦函数。

我们知道反正弦函数的傅里叶展开为:


依据这个式子就可以编写求解反正弦函数的代码,第一段代码如下:

float arm_asin(float in)
{
	float result = in, result_a = 1.0f, result_b = 1.0f, result_c = 1.0f;
	
	unsigned int i = 0, ii = 0;
	
	for(i = 0; i < 10; i++)
	{
		for(ii = 0; ii < (2 * i + 1); ii ++)
		{
			result_a *= (float)(2 * ii + 1) / (float)(2 * ii + 2); 
			result_b *= (in * in);
		}
		result_b *= in;
		result_c = result_a / (float)(ii + 2);
		result += (float)(result_c) * (float)result_b;
		result_a = 1.0f; result_b = 1.0f;
	}
	return result;
}

这段代码是完全按照计算式所得,但这样便遇到一个问题,那就是由于不同系统对浮点数运算的精度不同,会导致最终计算得到的精度出现较大的偏差。

从表达式里可以看出来,在多项式的第十项的时候其系数为0.00976160952919408000,此时计算反正弦值为0.5以内的时候,其精度为:0.00976160952919408000x0.5e21=4.6546981473894500732421875e-9,可见其精度还是很高的,但当反正弦值为1的时候,或非常接近1的时候,再看这个表达式,其精度就好打很大的折扣,再加上系统的精度损失则会很大程度上影响计算结果。

我在stm32f407vgt6单片机运行以上代码的结果如下:

================================================================

电脑计算器计算结果:arcsin(0.5) = 30

----------------------------------------------------------------------------------------------------------------

单片机计算结果a:arcsin(0.5)=29.870554(去泰勒展开前10项)

----------------------------------------------------------------------------------------------------------------

单片机计算结果b:arcsin(0.5)=29.870554(取泰勒展开前1024项)

================================================================

当然并不是没有办法提高其精度,一种简单的方法便是通过将系数预先计算出来做成数表,共系统查表,来降低由于系统计算所带来的精度损失,另一方面还可加快运行速度。

在实际应用用我们并不是这样在计算机中来计算一个表达式的结果的,对于对精度要求较高的场合更多的还是使用查表法来进行这种计算,在此不对这种方法进一步解释。




   
   
   







猜你喜欢

转载自blog.csdn.net/wolf_tong/article/details/71908151