求助! 奇怪的C语言计算偏差 求大佬解决

qq_34636559 2017-11-08 11:46:58
题目是这样的。。。。
在项目产生利润之前需要先投入建设资金(假设称为 c0),建成后每年产生的利润(假设称为 c1,c2…)。内部回报率(记为 r,范围为 −100%∽+100%)是到项目末期的现金流为 0 的贴现率。

例如:某项目建设资金为 10000,项目生产持续期为 3 年,每年利润为 3000,4000,5000,那么 r 满足:
−10000(1+r)^3+3000(1+r)^2+4000(1+r)+5000=0
Excel 计算结果 r 大约为 8.8963%。

本题的测试数据保证 r 只有唯一解。
Input
第 1 行:整数 T (1≤T≤10) 为问题数。
第 2∽3 行:第一个问题的数据。一行整数 n (1≤n≤100) 表示项目生产年数。后面 1 行包含 n+1 个由一个空格分隔的整数,表示投入的建设资金 c0 和 n 年中每年的利润 ci。c0>0,0≤ci≤1 000 000 000。
第 4∽2T+1 行:后面问题的数据,格式与第一个问题相同。

所以我觉得应该可以用牛顿迭代法做,,,,,但是遇到了奇怪的问题
下面的代码中举了个例子 为什么循环计算两次x得到的值 与计算一次 再将得到的值手动赋初值给x 再计算一次 得到的值不一样

输入值为 1 3 10 3 4 5时,即1个问题数,项目生产念书为3,投入建设资金为10,每年利润分别为3 4 5.
下面的代码循环计算两次x得到的值为0.093492
但是我如果将循环调成一次得到x的值是0.089060,再把这个值赋初值给x,再算一次,就成了0.088963
为啥 为啥 为啥
为啥 直接循环得不出正确答案?

讲道理 应该是一样的啊!!!为什么 ?C语言初学者 求各位大佬的解答。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
int n,i;int b,j;
scanf("%d",&n);
for(j=0;j<n;j++)
{
scanf("%d",&b);
double a[b+1];
for(i=0;i<b+1;i++)
{
scanf("%lf",&a[i]);
}


int i,n;double fx=0;double x=0.08;//赋初值给x
double fx1=0;

for(n=0;n<2;n++)//运算两次x
{
for(i=1;i<b+1;i++)//计算函数值
{
fx=fx+a[i]*pow(1.0+x,b-i);
}
fx=fx-a[0]*pow(1.0+x,b);

for(i=1;i<b;i++)//计算函数的导数值
{
fx1=fx1+a[i]*(b-i)*pow(1.0+x,b-i-1);
}
fx1=fx1-a[0]*pow(1+x,b-1)*b;

x=x-(fx/fx1);
}
printf("%lf\n",x);
}
return 0;
}
...全文
992 12 打赏 收藏 举报
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
qq_34636559 2017-11-08
就是第一次循环结束时的x值时对的,,但是当这个x值进入第二次循环的时候,得出的就不对了。。 然而把第一次循环得到的x值手动赋值给x,得到的是正确的。。。可以理解为电脑自动循环时得到的是错的。。。人工手动一次次计算。。是对的。。。。
  • 打赏
  • 举报
回复
das白 2017-11-08
设置断点调试一次啊 看那不一样
  • 打赏
  • 举报
回复
qq_34636559 2017-11-08
可是为什么 赋初值就可以了呢
  • 打赏
  • 举报
回复
赵4老师 2017-11-08
  • 打赏
  • 举报
回复
qq_34636559 2017-11-08
好像是的 谢谢啦 看来以后要多注意。
  • 打赏
  • 举报
回复
CT8100 2017-11-08
引用 10 楼 qq_34636559 的回复:
但是直接用for 就不行了
你看看 那是你程序的问题,你看看fx的值运行中不是也发生变化了么,把fx=0和fx1=0初始化放在循环中你再试试,结果就一样了
  • 打赏
  • 举报
回复
qq_34636559 2017-11-08
但是直接用for 就不行了
  • 打赏
  • 举报
回复
qq_34636559 2017-11-08
对 其他的不变 只把第一次得到的x值 替代原来的0.08 这样可以的得到正确答案
  • 打赏
  • 举报
回复
CT8100 2017-11-08
除了x的值变化其他的不变么?
  • 打赏
  • 举报
回复
CT8100 2017-11-08
引用 6 楼 qq_34636559 的回复:
那有没有什么办法解决呢
你所说的赋值是不是再把这行代码再执行一边呀? int i,n;double fx=0;double x=0.08;//赋初值给x
  • 打赏
  • 举报
回复
qq_34636559 2017-11-08
那有没有什么办法解决呢
  • 打赏
  • 举报
回复
CT8100 2017-11-08
引用 4 楼 qq_34636559 的回复:
就是第一次循环结束时的x值时对的,,但是当这个x值进入第二次循环的时候,得出的就不对了。。 然而把第一次循环得到的x值手动赋值给x,得到的是正确的。。。可以理解为电脑自动循环时得到的是错的。。。人工手动一次次计算。。是对的。。。。
不一样,因为精度问题,因为浮点类型的精度是最多能有7位有效数字,但绝对能保证的为6位,如果超过这个数据进行运算后,会自动进行省略小数点后的位数,所以导致第二遍循环的不准确。
  • 打赏
  • 举报
回复
相关推荐
发帖
C语言
加入

6.6w+

社区成员

C语言相关问题讨论
社区管理员
  • C语言
  • 小灸舞
申请成为版主
帖子事件
创建了帖子
2017-11-08 11:46
社区公告
暂无公告