谁能提供一下sin(x) cos(x)的数值计算公式?

fallening 2008-05-07 12:11:32
一般来说是用泰勒0点展开,但是要有1E-7的精度的话,可能要取20项的样子,如果要把sin(cos(x))展开实在是令人难以忍受;
请提供一个收敛比较快的公式,里边最好没有特殊函数
...全文
2160 45 打赏 收藏 转发到动态 举报
写回复
用AI写文章
45 条回复
切换为时间正序
请发表友善的回复…
发表回复
fallening 2008-05-11
  • 打赏
  • 举报
回复
我搞定了,多谢大家关注
大致思路是令sin(x) = sin(N*cos(y)),N取得足够大,然后用bessel函数展开
由于sin(Ncos(y)) = 2J(1,N)*sin(y) + 2J(3,N)sin(3y) + .....
由于sin(3y)可以用sin(y)递推过来,所以化简得以进行
还是使用了特殊函数,有点不太甘心,但是能够满足使用要求,也就将就了
结贴
Walker-cheng 2008-05-09
  • 打赏
  • 举报
回复
mark
wcwtitxu 2008-05-09
  • 打赏
  • 举报
回复
Mark
zhangbin_115 2008-05-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 baihacker 的回复:]
你可以参考一下里查得外推法
[/Quote]
英雄啊
莫_问 2008-05-08
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 bjsun 的回复:]
好,不错,……北京思源培训中心
[/Quote]


广告无处不在
fallening 2008-05-08
  • 打赏
  • 举报
回复
+100
baihacker 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 Chiyer 的回复:]
sin cos exp 是用泰勒公式和麦克劳林公式来计算。
为防止幂运算指数过高,在计算较大输入参数的时候容易导致溢出,考虑到sin和cos都是以2*PI为周期的,所以在函数内设置一个阀值(可自行修改,此处使用2*PI作为阀值),当实参大于阀值的时候,将其计算到-2*PI~2*PI象限,既防止了大数溢出问题,又提高了运算速度。
另外,误差范围也可自行控制。
[/Quote]

楼主的要求是需要更快的收敛速度

最简单的考虑是这样的

考虑对称性和反对称性,只考虑0-PI/2的情况
然后在0点或者PI/4这点展开,可能会有比较好的效果
liyuzhu_1984 2008-05-07
  • 打赏
  • 举报
回复
mark
星羽 2008-05-07
  • 打赏
  • 举报
回复

// cos
float fun_cos(float x, int m)
{
float ret_val;
int i;
if (m%2 == 0)
{
ret_val = 1.0;
}else
{
ret_val = -1.0;
}
for (i=1;i<=2*m;i++)
{
ret_val = ret_val * x/i;
}
return ret_val;
}
float cosx(float x)
{
float ret_val = 1.0;
float temp_ret;
int m = 1;
float Pi = 3.1415926;
if (x > 2*Pi || x < -2*Pi)
{
x = x-((int)(x/(2*Pi)))*(2*Pi);
}
do
{
temp_ret = fun_cos(x,m++);

ret_val += temp_ret;
} while (temp_ret>0.00005 || temp_ret<-0.00005);
return ret_val;
}

int main() {

for (double i = 0; i < 1; i += 0.01)
{
printf("%lf\n", cosx(i));
}

return 0;
}

星羽 2008-05-07
  • 打赏
  • 举报
回复
sin cos exp 是用泰勒公式和麦克劳林公式来计算。
为防止幂运算指数过高,在计算较大输入参数的时候容易导致溢出,考虑到sin和cos都是以2*PI为周期的,所以在函数内设置一个阀值(可自行修改,此处使用2*PI作为阀值),当实参大于阀值的时候,将其计算到-2*PI~2*PI象限,既防止了大数溢出问题,又提高了运算速度。
另外,误差范围也可自行控制。
星羽 2008-05-07
  • 打赏
  • 举报
回复

// sin


float fun_sinx(float x, int m)
{
float ret = 0.0;
int i = 0;
if (m%2 == 0)
{
ret = -1.0;
}else
{
ret = 1.0;
}
for (i=1;i<=2*m-1;i++)
{
ret = ret * x/i;
}

return ret;
}

float sinx(float x)
{
int m = 1;
float tempRet;
float retVal = 0.0;
float Pi = 3.1415926;
if (x > 2*Pi || x < -2*Pi)
{
x -=((int)(x/(2*Pi)))*(2*Pi);
}

do
{
tempRet = fun_sinx(x,m);
retVal += tempRet;
m++;
} while (tempRet<-.0000005||tempRet>0.0000005);
return retVal;
}

int main() {

for (double i = 0; i < 1; i += 0.01)
{
printf("%lf\n", sinx(i));
}

return 0;
}


xiaoc10 2008-05-07
  • 打赏
  • 举报
回复
关注。。。
fallening 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 baihacker 的回复:]
你可以参考一下里查得外推法
[/Quote]
Richardson Extrapolation么? 正在看,谢谢
fallening 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 baihacker 的回复:]
你可以参考一下里查得外推法
[/Quote]
Richardson Extrapolation么? 正在看,谢谢
baihacker 2008-05-07
  • 打赏
  • 举报
回复
你可以参考一下里查得外推法
fallening 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xkyx_cn 的回复:]
只要考虑算法就行,其他的计算机去替你做
[/Quote]
我要作一个具体的计算,与sin(x)中的x有关;x不是一个具体的数值,是一个函数,计算机怎么帮我去做?
xkyx_cn 2008-05-07
  • 打赏
  • 举报
回复
只要考虑算法就行,其他的计算机去替你做
COASTLINE001 2008-05-07
  • 打赏
  • 举报
回复
这个实在是牛逼!
jeff_nie 2008-05-07
  • 打赏
  • 举报
回复
mark.
fallening 2008-05-07
  • 打赏
  • 举报
回复
多谢提醒,我过去再开一个帖子吧
加载更多回复(24)

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧