今日 有一位同样读大一的朋友向我求助有关c++的作业题 他说他的程序逻辑正确 但是结果的精度不对

题目如下:

这是一道看起来十分简单的作业题 我按照要求快速地写了一个版本 不出所料 一样遇到了精度问题

为什么会出现这种问题?

首先 计算机中的浮点数是不够精确的 这是为了运算速度所做的牺牲

在我写的代码中 使用的是double 为了使结果精确 要能尽量减少不必要的计算过程

而我用了cmath头文件中的pow函数 这使得double会被计算很多次导致结果精度降低

于是我决定写一个无pow版本 从公式出发 思路如下:

原式化简:

sin(x) = x/1! - x^3/(1!*2*3) + x^5/(3!*4*5) - x^7/(5!*6*7) ...

拆分:

sin(x)= x/1!
- x^3/(1!*2*3)
+ x^5/(3!*4*5)
- x^7/(5!*6*7)
...

拆分之后我们可以尝试用一个变量去替换其中的数字:

sin(x)= x/1!
[i=1] - x^3/(i!*(i+1)*(i+2))
[i=3] + x^5/(i!*(i+1)*(i+2))
[i=5] - x^7/(i!*(i+1)*(i+2))
[i=n] ...

引入一个变量p 替换幂:

p=x
sin(x)= p/1!
[i=1,p=p*x*x] - p/(i!*(i+1)*(i+2))
[i=3,p=p*x*x] + p/(i!*(i+1)*(i+2))
[i=5,p=p*x*x] - p/(i!*(i+1)*(i+2))
[i=n,p=p*x*x] ...

再引入一个变量f 替换阶乘:

f=1
p=x
sin(x)= p/f
[i=1,p=p*x*x,f=f*(i+1)*(i+2)] - p/f
[i=3,p=p*x*x,f=f*(i+1)*(i+2)] + p/f
[i=5,p=p*x*x,f=f*(i+1)*(i+2)] - p/f
[i=n,p=p*x*x,f=f*(i+1)*(i+2)] ...

再引入一个变量n 替换其中的负号:

n=1
f=1
p=x
sin(x)= p/f
[i=1,p=p*x*x,f=f*(i+1)*(i+2),n=-n] + n*p/f
[i=3,p=p*x*x,f=f*(i+1)*(i+2),n=-n] + n*p/f
[i=5,p=p*x*x,f=f*(i+1)*(i+2),n=-n] + n*p/f
[i=n,p=p*x*x,f=f*(i+1)*(i+2),n=-n] ...

现在每项的式子完全相同了 只需将其转换成对应的程序
我们要考虑结束条件 即当其中一项的绝对值小于1.0e-7时 结束这个循环

最终答案 :

 double x;
cout << "请输入角度值:";
cin >> x; x = x * 3.141592654 / ; double n = ;
double f = ;
double p = x;
double i = -; double term = ;
double result = p / f; while ()
{
i += ;
p = p * x * x;
f = f * (i + ) * (i + );
n = -n;
term = p / f;
if (term < 1.0e-7)
break;
result = result + n * term;
}
cout << "对应的sin值为:" << result << endl;

结果正确:

再看看朋友的代码:

 double angel,term,sum=,i=,multi=,sign=-;
const double pi=3.141592654;
cout<<"请输入角度值:";
cin>>angel;
angel=angel*pi/;
term=angel;
while(term>=1.0e-7||term<=-1.0e-7)
{
sum+=term;
angel*=angel*angel;
multi*=(i+)*(i+);
term=sign*angel/multi;
sign*=-;
i+=;
}
cout<<"对应的sin值为:"<<sum<<endl;

结果:

思路大致和我相同 但是其中一步 angel*=angel*angel; 不对
在我的代码中 这一步对应的是 p = p * x * x; 其中x是不变的 他代码的这一部分并不等效于sin公式

END

c++作业题sin公式的更多相关文章

  1. 1137 - Sin your life sin公式 + 枚举

    http://www.ifrog.cc/acm/problem/1137 和差化积公式, 变成2 * sin((x + y) / 2) * cos((x - y) / 2) + sin(n - (x ...

  2. java web 运动前端

    [写在前面的话:]前不久刚看到过一句话:说好的技术文章应该让读者感觉增加信心,而不是失去信心.有感于这句话是因为以前觉得发一些貌似高深的,看起来nb的东西才算一篇好博文,可是多少有点炫技的成分.可是后 ...

  3. sin n次方 x 的降幂公式

    A(n) = ∫ sinⁿx dx= ∫ sinⁿ⁻¹xsinx dx= - ∫ sinⁿ⁻¹x d(cosx)= - sinⁿ⁻¹xcosx + ∫ cosx • d(sinⁿ⁻¹)= - sinⁿ ...

  4. 正割、余割、正弦、余弦、正切、余切之间的关系的公式 sec、csc与sin、cos、tan、cot之间的各种公式

    1.倒数关系 tanα ·cotα=1 sinα ·cscα=1 cosα ·secα=1 2.商数关系 tanα=sinα/cosα cotα=cosα/sinα 3.平方关系 sinα²+cosα ...

  5. “玲珑杯”线上赛 Round #17 河南专场 A: Sin your life(和化积公式)

    传送门 题意 略 分析 首先将sin(x)+sin(y)+sin(z)h转化成\(2*sin(\frac{x+y}2)*cos(\frac{x-y}2)+sin(z)\),而cos(z)=cos(-z ...

  6. Tween公式 以及四个参数

    Tween的主页在这里:http://createjs.com/tweenjs , 这里边还有挺多开源项目的: Tween公式 4个参数 t:current time(当前时间) b:beginnin ...

  7. UVA 11817 Tunnelling the Earth --球面距离公式

    题意: 给出两点的经纬度,求两点的球面距离与直线距离之差. 解法: 我们先算出球面距离,然后可以根据球面距离算出直线距离. 球面距离公式: R*acos(sin(W1)*sin(W2)+cos(W1) ...

  8. LaTex学习笔记——LaTeX公式换行

    ps.  1.“\!” 表示其前后字符之间无间隙        2.暂留        3.段落中的数学表达式应该置于( 和), $ 和$ 或者begin{math} 和end{math} 之间.   ...

  9. [家里蹲大学数学杂志]第237期Euler公式的美

    1 Euler 公式 $e^{i\pi}+1=0$ (1) 它把 a.  $e:$ 自然对数的底 $\approx 2. 718281828459$ (数分) b.  $i$: 虚数单位 $=\sqr ...

随机推荐

  1. WC.exe(Java实现)

    一.GitHub项目地址:https://github.com/nullcjm/mypage 二.项目相关要求: wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写 ...

  2. .net web api 权限验证

    做一个登录权限验证. 开始吧. using System; using System.Collections.Generic; using System.Drawing; using System.D ...

  3. 将积累多年的java学习资料,pdf文档给大家分享一下,比如《大话设计模式》《算法》《Linux私房菜》等等

    话不多说,资料目录如下,需要的拿走,下载的同时别忘了点下推荐. 需要的点下面链接,到小编网盘进行下载: 2-大话设计模式.pdf 链接:https://pan.baidu.com/s/1b05puNO ...

  4. eclipse activiti 不能自动生成png图片解决方案

    1. Windows-->Preferences 2. Activiti-->Save Actions-->勾选 Create process definition ... --&g ...

  5. Linux进程管理之top

    关于Linux进程查看,前面讲解了ps命令,下面拉介绍另一个命令top ps:静态查看 top:动态查看 动态查看进程的状态 # top [root@wei ~]# top top - 18:38:4 ...

  6. OpenSSL 安装 (Linux系统)

    OpenSSL 编译安装 操作系统:CentOS 7 OpenSSL Version: openssl-1.1.1d.tar.gz OpenSSL下载地址为:https://www.openssl.o ...

  7. java lambda表达式检查list集合是否存在某个值

    import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class ...

  8. face-api.js:一个在浏览器中进行人脸识别的 JavaScript 接口

    Mark! 本文将为大家介绍一个建立在「tensorflow.js」内核上的 javascript API——「face-api.js」,它实现了三种卷积神经网络架构,用于完成人脸检测.识别和特征点检 ...

  9. Q1094

    一,看题 1,字符串确实是我的弱项. 2, 二,看题解 #include<iostream> #include<string> using namespace std; int ...

  10. learning shell check requires root privileges

    [Purpose]        Shell script check requires root privileges   [Eevironment]        Ubuntu 16.04 bas ...