| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5312 人关注过本帖
标题:[原创]正弦和反正弦函数
只看楼主 加入收藏
乌鸦丘比特
Rank: 1
等 级:新手上路
威 望:2
帖 子:625
专家分:0
注 册:2004-7-19
收藏
 问题点数:0 回复次数:3 
[原创]正弦和反正弦函数

记得曾经有人提出过这个问题——如何模拟正弦函数。

我试着编了一个正弦和反正弦的函数。

算法:二分搜索,有些像搜索算法里的二分法,算试一种推广吧,我在单位圆里面对单位圆上的 坐标进行二分搜索,直到找到匹配的坐标为止;

——经过测试,和标准数学函数的正弦函数误差 几乎为0,

由于水平有限,让大家见笑了。

下面贴出代码(有注释,如果不懂,请提出来):

/*正弦和反正弦函数*/ /*为了和标准数学函数区别,正弦函数为sinof()反正弦函数为arcsin()*/ #include <math.h> typedef struct num{double x;double y;}num; num *midof(num *a,num *b) /*求角平分线于单位圆的交点*/ {double x1,y1,z; num *mid=(num*)malloc(sizeof(num)); x1=(a->x+b->x)/2; y1=(a->y+b->y)/2; z=sqrt(100000000/(x1*x1+y1*y1)); mid->x=z*x1; mid->y=z*y1; return mid;}

double doarcsin(double n) /*搜索函数,可以搜索0-1*/ {num *a=(num*)malloc(sizeof(num)); /*a为上界,b为下界,mid为中间坐标*/ num *b=(num*)malloc(sizeof(num)); num *mid=(num*)malloc(sizeof(num)); double f,t,answer,s,i=45; a->x=0;a->y=10000; answer=90; /*尽量让坐标数值大,充分利用double的整数位,保证精确搜索*/ b->x=10000;b->y=0; t=10000*n;f=sqrt(100000000-t*t); mid=midof(a,b); s=(mid->x-f)*(mid->x-f)+(mid->y-t)*(mid->y-t); /*当sin 值达于0.6时以横坐标为判断*/ if(n>=0.6){while(s>=0.0000000001) { if(mid->x>f){b->x=mid->x;b->y=mid->y;i=i/2;} if(mid->x<=f){a->x=mid->x;a->y=mid->y;answer=answer-i;i=i/2;} mid=midof(a,b); s=sqrt((mid->x-f)*(mid->x-f)+(mid->y-t)*(mid->y-t)); } } else {while(s>=0.0000000001) { /*以纵坐标判断*/ if(mid->y<t){b->x=mid->x;b->y=mid->y;i=i/2;} if(mid->y>=t){a->x=mid->x;a->y=mid->y;answer=answer-i;i=i/2;} mid=midof(a,b); s=sqrt((mid->x-f)*(mid->x-f)+(mid->y-t)*(mid->y-t)); }} free(a); free(b); free(mid); return answer; } double arcsin(double n) /*反正弦函数,把所有情况化为0-1的情况然后求解*/ {if(n>1||n<-1){printf("wrong input\n");getch();exit(0);} else if(n>=0)return (doarcsin(n)); else return (-1*doarcsin((-1*n))) ;}

double dosinof(double n) /*正弦搜索函数,计算0-90度的正弦值*/ {num *a=(num*)malloc(sizeof(num)); /*a为上界,b为下界,mid为中间坐标*/ num *b=(num*)malloc(sizeof(num)); num *mid=(num*)malloc(sizeof(num)); double answer,s,now=45000000,i=45000000; /*把角度扩大了1000000倍,充分利用double的整数位置,也是搜索准确的关键所在*/ n=n*1000000;

a->x=0;a->y=10000; answer=90; b->x=10000;b->y=0; mid=midof(a,b); s=abs(i-n); i=(i/2); while(s>=0.0000000001)

{ if(now>n){a->x=mid->x;a->y=mid->y;now=now-i;i=(i/2); } else if(now<=n){b->x=mid->x;b->y=mid->y;now=now+i;i=(i/2);} mid=midof(a,b); s=abs(now-n); } answer=mid->y/10000; free(a); free(b); free(mid); return answer;} double sinof(double n) /*正弦函数,把所有情况化归到0-90度然后解决*/ {while(n>180||n<(-180)) {if(n>180)n=n-360; if(n<(-180))n=n+360; } if(n>90)n=180-n; if(n<(-90))n=n+180; if(n>=0)return dosinof(n); else return (-1*dosinof((-1)*n));}

搜索更多相关主题的帖子: 正弦 函数 
2004-08-18 20:08
乌鸦丘比特
Rank: 1
等 级:新手上路
威 望:2
帖 子:625
专家分:0
注 册:2004-7-19
收藏
得分:0 

如果有兴趣可以测试一下,注意我的函数和标准函数有一个不同点——我的是用角度制的,

标准函数是用弧度制的,所以测试时要把标准函数也转化为角度制,

弧度转化角度方法就是弧度*90/asin(1){由于没有Π(圆周率),只能借助反正弦函数了)

给一个参考测试函数:

main(){ double t=; /*t的值自己加,测试正弦函数*/ printf("%lfVS%lf=%lf\n",sinof(t),sin(t*asin(1)/90),sinof(t)-sin(t*asin(1)/90));getch();}

/*前一个是我的函数值,后一个是标准函数值,再后面是两数差*/

main()

{double t=; /*t的值自己加,注意范围-1——1,测试反正弦函数*/

printf("%lfVS%lf=%lf\n",arcsin(t),asin(t)*90/asin(1),arcsin(t)-asin(t)*90/asin(1)); getch();}

/*前一个是我的函数值,后一个是标准函数值,再后面是两数差*/


我喜欢创造,一只扑腾着翅膀向天空飞翔的乌鸦
2004-08-18 20:21
live41
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:67
帖 子:12442
专家分:0
注 册:2004-7-22
收藏
得分:0 

不知所云~~~

顶一个!不是说你写得不好,而我资质差,对不起你了~~~

2004-08-19 10:55
chengstone
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
帖 子:562
专家分:226
注 册:2004-4-3
收藏
得分:0 
呵呵 军训了一个礼拜 没把我累死 今天一来论坛就看到了这个 不错 顶一下 不过偶对数学没什么研究~~

qq:69558139
2004-08-24 16:18
快速回复:[原创]正弦和反正弦函数
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015169 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved