《C语言及程序设计》实践参考——sin泰勒展式中的错误
来源:互联网 发布:mac 鼠标右键不能用 编辑:程序博客网 时间:2024/05/22 13:05
返回:贺老师课程教学链接 项目要求
【项目1-sin泰勒展式中的错误】
下面是sin函数的泰勒展式:
(注:x取弧度值,而非角度值)
编写了double mysin(double x)用于求sin值,却“死”在了123°上(122°度的结果已经出来了)。剧透一下,循环没有问题(当然问题会表现在循环中)。试着用调试工具找出问题出现在哪里,然后给出解决问题的方案。
#include<stdio.h>#define pi 3.1415926double mysin(double x);double myabs(double x);int main( ){ double angle; for(angle=0; angle<=180; angle++) printf("sin(%.0f°) = %.3f\n", angle, mysin((angle/180)*pi)); return 0;}//下面定义mysin函数,求sin值double mysin(double x){ double sum=x,x_pow=x,item; int n=1,fact=1, sign=1; //定义变量时赋初值,已经将第一项考虑到累加和sum中 do { fact=fact*(n+1)*(n+2); //fact用于表示阶乘,在公式中作分母 x_pow*=x*x; //x_pow是分子中用于表示阶乘,在公式中作分母 sign=-sign; //确定即将要累加的这一项的符号 item =x_pow/fact*sign; //计算出要累加的项 sum+=item; //将该项累加上去 n+=2; }while(myabs(item)>1e-5); return sum;}//下面定义myabs函数double myabs(double x){ return ((x>=0)?x:-x);}提示:请进入到mysin中后,注意各变量的变化,看通项是否会收敛,从而使循环能够结束。
[参考解答]
(若需要参考,下面的锦囊逐个找开。你要是将所有锦囊全看了再干,……老贺会伤心的:每个锦囊里都有心血,一个一个做出来不容易。)
(若你在实施中,还有意外阻碍了你,请在评论中说明,帮助老贺细化锦囊。)
锦囊1:跟踪要进到mysin函数中,注意用step into。
锦囊2:跟踪mysin函数的执行,离不了进循环,你要是一直用next line(用step into不遇到自定义函数时效果也一样),点鼠标很单调,还容易分散注意力。请在循环中某语句上设置断点,用Debug/Continue按钮“跨越式”跟踪。
锦囊3:因为问题出在123°,你要是从0°开始跟踪mysin中的循环,我相信你看到这个锦囊时,大概angle不超过10(这已经说明你有足够的耐心了)。我们需要直接进入到对当角度是123°时对mysin的调用。有两种方法:
第一种:改一下main函数,例如(还可以有很多方式,只要能直接调用mysin(123°)即可):
int main( ){ double angle; printf(" %.3f\n", mysin((123/180)*pi)); //for(angle=0; angle<=180; angle++) // printf("sin(%.0f°) = %.3f\n", angle, mysin((angle/180)*pi)); return 0;}第二种:在观察窗口(Watches)中,还可以在跟踪中改变变量的值,以便看到对应的执行结果。所以如下图,可以在进入到mysin函数之前,在观察窗口中加入angle(需要在系统自动出现的变量的下面,自己再输入变量名),然后在后面直接将想要的值输入。
其实还可以step into到mysin中后(或者通过断点直接进入到mysin中后),同样的办法修改x的值。
锦囊4:很可能你听了老贺的指点,用锦囊3中的第一种方法,却发现进到mysin后,x的值是0,不是123°对应的弧度值。
对不起,我故意挖个坑,你也就进来了。进来了,坐会儿再走。
求123°的sin值,不是调用mysin((123/180)*pi),而是mysin((123.0/180)*pi)!mysin((123/180)*pi)的确就是mysin(0),注意数据类型。
进了这个坑,就要知道,程序的修改,可能会引入新的错误。这是软件工程中的一个规律。
锦囊5:现在进入关键时刻(建议还是设好断点跟踪),你会发现问题在于,item的绝对值本来是逐渐递减趋于0的(这体现了泰勒公式的收敛性,实际上,当角度值没有达到123°时,这种收敛是能保证的),但是,某个时候,item的绝对值却又大了起来,退出循环的希望,逐渐渺茫,以致于失去了希望……你可以观察fact的值,这里也发生了一些似乎不可思议的事情。
锦囊到此,现象都有了,下面就需要你的诊断了。请试着解决这个问题。解决了,或者实在想不出来了,再看下面的“真相”。
真相(倒着看,一来你得活动活动身体了,二来,实在不想让你很容易地放弃自己给出解决方案的探索历程):
- 《C语言及程序设计》实践参考——sin泰勒展式中的错误
- 《C语言及程序设计》实践参考——输出点阵图
- 《C语言及程序设计》实践参考——电阻并联
- 《C语言及程序设计》实践参考——正差值
- 《C语言及程序设计》实践参考——发工资
- 《C语言及程序设计》实践参考——玩数字
- 《C语言及程序设计》实践参考——坐标转换
- 《C语言及程序设计》实践参考——构造菜单
- 《C语言及程序设计》实践参考——投票表决器
- 《C语言及程序设计》实践参考——成绩等级
- 《C语言及程序设计》实践参考——求阶乘
- 《C语言及程序设计》实践参考——另类求和
- 《C语言及程序设计》实践参考——Bessel函数
- 《C语言及程序设计》实践参考——转着圈加密
- 《C语言及程序设计》实践参考——血型统计
- 《C语言及程序设计》实践参考——大奖赛计分
- 《C语言及程序设计》实践参考——打豆豆
- 《C语言及程序设计》实践参考——完数
- ZOJ3875:Lunch Time(浙江省赛2015)
- 第五题
- 最近点对问题
- [LeetCode]Longest Common Prefix
- Facebook的开源动画库popAnimation
- 《C语言及程序设计》实践参考——sin泰勒展式中的错误
- linux之软链接,硬链接
- The 12th Zhejiang Provincial Collegiate Programming Contest
- 《C语言及程序设计》实践参考——总是多一次?
- .Net——动态调用方法
- 王家林 构建spark集群
- ZOJ3872:Beauty of Array(浙江省赛2015)
- 第8周项目2Time类中的运算符重载
- 十大前端开发框架