鱼C论坛

 找回密码
 立即注册
查看: 1877|回复: 3

[已解决]求助!C语言中计算精度问题

[复制链接]
发表于 2017-6-21 12:28:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 留恋流年 于 2017-6-22 00:34 编辑

断断续续两天时间,目测逻辑上应该没问题啊,最终结论 r 应该不等于 f1 且 k1<1

有些公式会影响代码阅读。
但是这不重要,我确定公式没问题

那么问题来了

在C语言中,double的精度会在计算过程丢失吗?
同样的公式,我用笔算,人力有限,只保留了4位小数。而double好像是15位有效数字。然后经过多次的运算,误差就越来越大。笔算结果和程序输出
自然就不一样。

那么,可能会造成笔算a-b=1   而程序计算结果 a-b=0.000001 的情况吗???

求解答

贴代码

  1. #include<stdio.h>
  2. #include<math.h>
  3. #define PI 3.1415926
  4. #define t PI/180
  5. int main(void)
  6. {
  7.                
  8.         int i;
  9.         double p0,p1,p2,a0,b0,m,n,l,a5;         
  10.         double A,B,C,r,s,f1,f2,k1,j;        /*定义变量 */
  11.         double u1=1.0/45,u2,x0=1.0,xm=2.0,ym=1.414,y0=1.0; /*定自变量、函数与转角的比例尺*/
  12.         double a[3],b[3],a1[6],b1[3],k[3];
  13.         u2=(sqrt(2)-1)/85;
  14.         int ii,jj;
  15.         double x[3],y[3];
  16.         printf("各结点处的有关各值如下:\n");
  17.         for(ii=0;ii<3;ii++)       
  18.         {
  19.                 x[ii]=(1.0/2.0*(xm+x0))-(1.0/2.0*(xm-x0)*cos((2*(ii+1)-1)*PI/6));
  20.                 y[ii]=sqrt(x[ii]);
  21.                 a[ii]=(x[ii]-x0)/u1;
  22.                 b[ii]=(y[ii]-y0)/u2;
  23.                 printf("x[%d]=%-12lf y[%d]=%-12lf α[%d]=%-12lf ψ[%d]=%-12lf\n",ii+1,x[ii],ii+1,y[ii],ii+1,a[ii],ii+1,b[ii]);
  24.         }       
  25.         printf("\n\n");

  26.           for (jj=0;jj<10;jj++)
  27.          {
  28.                  printf("please input a0: \n");
  29.                 scanf("%lf",&a0);
  30.                 printf("please input ψ0: \n");
  31.                 scanf("%lf",&b0);//        a0=85;b0=30;

  32.                  for(i=0;i<3;i++)
  33.                  {
  34.                          a1[i]=cos((b[i]+b0)*t);
  35.                          a1[i+3]=cos((b[i]+b0-a[i]-a0)*t);
  36.                          b1[i]=cos((a[i]+a0)*t);
  37.                 }
  38.                 p0=((b1[0]- b1[1])*(a1[4]-a1[5])-(b1[1]-b1[2])*(a1[3]-a1[4]))/((a1[0]-a1[1])*(a1[4]-a1[5])-(a1[1]-a1[2])*(a1[3]-a1[4]));
  39.                 p1=(b1[0]-b1[1]-(a1[0]-a1[1])*p0)/(a1[3]-a1[4]);
  40.                 p2=b1[0]-a1[0]*p0-a1[3]*p1;
  41.                  
  42.                 m=p0;
  43.                 n=-m/p1;
  44.                 l=sqrt(m*m+n*n+1-2*n*p2);
  45.                  
  46.                 printf("p0=%-12lf p1=%-12lf p2=%-12lf \n m=%-12f  n=%-12lf  l=%-12f\n",p0,p1,p2,m,n,l);
  47.                 printf("\n");
  48.                 printf("检查偏差值△ψ,数据如下:\n");                //前面基本没有问题,最后的检查时 r 应该不等于 f1 且 k1<1
  49.                 for (ii=0;ii<3;ii++)
  50.                 {
  51.                         printf("当α=%lf时:\n",a[ii]);
  52.                          A=sin((a[ii]+a0)*t);
  53.                         B=cos((a[ii]+a0)*t)-n;
  54.                         C=(1+m*m+n*n-l*l)/(2*m)-n*cos((a[ii]+a0)*t)/m;
  55.                         j=x0+u1*a[ii];
  56.                  
  57.                         printf("A=%-12lf   B=%-12lf   C=%-12lf\n",A,B,C);
  58.                  
  59.                         s=sqrt(A*A+B*B-C*C);
  60.                        
  61.                         if((B+C)<0.0)
  62.                         {f1=2*(atan((A-s)/(B+C)))/(t)-b0;}        //f1=ψ
  63.                         else if((B+C)>0.0)
  64.                         {f1=2*(atan((A+s)/(B+C)))/(t)-b0;}
  65.                         r=(sqrt(j)-y0)/u2;                                        //r=ψ'   
  66.                         k[ii]=f1-r;
  67.                         printf("ψ=%-12lf ψ'=%-12lf △ψ=%-12lf\n\n",f1,r,k[ii]);
  68.                  
  69.                 }
  70.                 if(labs(k[0])<1&&labs(k[1])<1&&labs(k[2])<1)
  71.                 {
  72.                          printf("当初始角αo=%.2lf,ψo=%.2lf时:△ψ<1°则初始角合格!\n",a0,b0);
  73.                          break;
  74.                 }
  75.                 printf("试取初始角不合格!请继续试取下一组\n");
  76.          }
  77.          
  78.                  
  79.          for(i=0,a5=0;a5<=45;i++,a5+=0.5)
  80.         {
  81.                
  82.                 printf("当α=%lf时:\n",a5);
  83.                  A=sin((a5+a0)*t);
  84.                  B=cos((a5+a0)*t)-n;
  85.                  C=(1+m*m+n*n-l*l)/(2*m)-n*cos((a5+a0)*t)/m;
  86.                  j=x0+u1*a5;
  87.                  
  88.                  printf("A=%-12lf  B=%-12lf  C=%-12lf\n",A,B,C);
  89.                  
  90.                  s=sqrt(A*A+B*B-C*C);
  91.                  if((B+C)>0)
  92.                  f1=2*(atan(A+s)/(B+C))/(t)-b0;        //f1=ψ的正值
  93.                  else if((B+C)<0)f1=2*(atan((A-s)/(B+C)))/(t)-b0;//f1=ψ的负值

  94.                 r=(sqrt(j)-y0)/u2;                //r=ψ'   
  95.                  k1=f1-r;
  96.                  
  97.                  printf("ψ=%-12lf ψ'=%-12lf △ψ=%-12lf\n",f1,r,k1);
  98.                  
  99.                 printf("\n\n");
  100.                  
  101.         }
  102.         return 0;
  103. }

  104.         {
复制代码
最佳答案
2017-6-22 01:16:02
留恋流年 发表于 2017-6-22 00:35
啊啊啊啊,老师,求助啊啊@小甲鱼
在C语言中,double的精度会在计算过程丢失吗?

99% 的语言中,浮点数的精度都不是 100% 精确的!C 语言也不例外,千万不要拿浮点数作为判断的条件。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-22 00:35:47 | 显示全部楼层
啊啊啊啊,老师,求助啊啊@小甲鱼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-22 01:16:02 | 显示全部楼层    本楼为最佳答案   
留恋流年 发表于 2017-6-22 00:35
啊啊啊啊,老师,求助啊啊@小甲鱼
在C语言中,double的精度会在计算过程丢失吗?

99% 的语言中,浮点数的精度都不是 100% 精确的!C 语言也不例外,千万不要拿浮点数作为判断的条件。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-22 10:00:33 | 显示全部楼层
小甲鱼 发表于 2017-6-22 01:16
99% 的语言中,浮点数的精度都不是 100% 精确的!C 语言也不例外,千万不要拿浮点数作为判断的条件。

请问老师,那应该怎么做?真的不懂了。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 16:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表