求解方程

来源:互联网 发布:阿里云备案服务器费用 编辑:程序博客网 时间:2024/04/26 21:41
求解方程:
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#include <stdlib.h>
 
doubleFunc(double);
intBisectRoot(double,double,double,double,double *,int,int *);
 
voidmain()
{
         inti,n,m;
         doublea,b,h,eps,*x;
         n = 3;                                                        /*方程根的个数的预估值*/
         x = (double*)calloc(n,sizeof(double));                   /*开辟内存空间*/
         if(x == NULL)
         {
                   printf("内存分配失败/n");
                   exit(1);
         }
         a = -3;                                                                         /*区间起始端点*/
         b = 7;                                                                          /*区间终止端点*/
         h = 0.1;                                                              /*步长*/
         eps = 1.e-8;                                                        /*要求达到的精度*/
         BisectRoot(a,b,h,eps,x,n,&m);                   /*调用二分法函数*/
         printf("y=sin(x)在范围%2.0f%2.0f之间的根有%d个根/n",a,b,m);
         printf("它们分别是:/n");
         for(i = 0;i<n;i++)
         printf("x[%d] = %e/n",i,x[i]);
         free(x);                                           /*释放内存空间*/
}
 
doubleFunc(doublex)
{
         return(sin(x));
}
 
intBisectRoot(a,b,h,eps,x,n,m)
doublea;                    /*实型变量,输入参数,求根区间的起始端点*/
doubleb;                    /*实型变量,输入参数,求根区间的终止端点*/
doubleh;                    /*利用逐步扫描法确定根位置时的步长*/
doubleeps;                          /*实型变量,输入参数,控制精度的参数*/
double *x;                            /*实型一维数组,输出参数,存放计算得到的数组*/
intn;                                      /*输入参数,区间内方程根的个数的预估值*/
int *m;                                   /*输出参数,实际求得的根的个数*/
{
         doublez,z0,z1,y,y0,y1;
         *m = 0;
         z = a;
         y = Func(z);
         while(1)              /*无限循环,直到遇到return或者break语句*/
         {/*如果逐步扫描到求根区间的右端点或者得到的根的个数达到预估根的个数*/
                  if((z>b+h/2)||(*m==n)) 
                            return(1);
                  if(fabs(y)<eps)             /*如果当前根z对应的函数f(z)满足精度要求*/
                   {
                            *m+=1;
                            x[*m-1] = z;         /*将此时的z值赋值给x数组*/
                            z+=h/2;
                            y = Func(z);
                            continue;          /*结束本次循环,即跳过循环体中下面尚未执行
                                                                  的语句接着进行下一次是否执行循环的判定*/
                   }
        
                   z1 = z+h;                    /*逐步扫描中小区间的右端点*/
                   y1 = Func(z1);           /*小区间右端点对应的函数值*/
                  if(fabs(y1)<eps)    /*如果右端点恰好满足根的精度要求*/
                   {
                            *m+=1;
                            x[*m-1] = z1;
                            z = z1+h/2;
                            y = Func(z);
                            continue;
                   }
                  if(y*y1>0)                            /*如果对应根乘积大于零,说明该区间内没有根*/
                   {
                            y = y1;                           
                            z = z1;
                            continue;
                   }
                  while(1)                   /*如果本while循环执行,说明逐步扫描小区建zz1间有根*/
                   {
                            if(fabs(z1-z)<eps)                  /*如果满足精度要求*/
                            {
                                     *m+=1;
                                     x[*m-1]=(z1+z)/2;
                                     z = z1+h/2;
                                     y = Func(z);
                                     break;
                            }
                            z0 = (z1+z)/2;                             /*二分发求根公式*/
                            y0 = Func(z0);
                            if(fabs(y0)<eps)
                            {
                                     *m = *m+1;
                                     x[*m-1] = z0;
                                     z =z0+h/2;
                                     y = Func(z);
                                     break;
                            }
                            if(y*y0<0)                            /*如果乘积小于零,说明根在zz0之间*/
                            {
                                     z1 = z0;
                                     y1 = y0;
                            }
                            else                             /*否则根在z0z1之间*/
                            {
                                     z = z0;
                                     y = y0;
                            }
                   }
         }
}

牛顿迭代法:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
 
intFunction(double,double *,double *);
intNewton(double *,double,int);
 
intFunction(x,f,dy)
doublex;
double *f;
double *dy;
{
         *f = x*x*(x-1)-1;
         *dy = 3*x*x-2*x;
         return(1);
}
 
intNewton(x,eps,l)
double *x;
doubleeps;
intl;
{
         doublef,dy,x1;
         Function(*x,&f,&dy);
A:     if(fabs(dy) == 0)
         {
                   l = 0;
                   return (0);
         }
         x1=*x-f/dy;
         Function(x1,&f,&dy);
         if(fabs(x1-*x)>=eps||fabs(f)>=eps)
         {
                   l-=1;
                   *x=x1;
                   if(l==0)
                            return(1);
                   gotoA;
         }
         *x = x1;
         return 1;
}
 
voidmain()
{
         doublex,eps;
         intl;
         eps=1.e-6;
         x=1.5;
         l=60;
         if(!Newton(&x,eps,l))
         {
                   printf("该函数不可以用牛顿跌代法求根!/n");
         }
         printf("利用牛顿跌代法求的的根为:/n");
         printf("x=%.10f/n",x);
}

弦节法:
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#include <stdlib.h>
 
doubleFunc(double);
intBowRoot(double,double,double,double,double *,int,int *);
 
voidmain()
{
         inti,n,m;
         doublea,b,h,eps,*x;
         n = 3;                                                        /*方程根的个数的预估值*/
         x = (double*)calloc(n,sizeof(double));                   /*开辟内存空间*/
         if(x == NULL)
         {
                   printf("内存分配失败/n");
                   exit(1);
         }
         a = -3;                                                                         /*区间起始端点*/
         b = 5;                                                                          /*区间终止端点*/
         h = 1;                                                                          /*步长*/
         eps = 1.e-8;                                                        /*要求达到的精度*/
         BowRoot(a,b,h,eps,x,n,&m);                   /*调用二分法函数*/
         printf("函数f(x)在范围%2.0f%2.0f之间的根有%d个根/n",a,b,m);
         printf("它们分别是:/n");
         for(i = 0;i<n;i++)
         printf("x[%d] = %e/n",i,x[i]);
         free(x);                                           /*释放内存空间*/
}
 
doubleFunc(doublex)
{
         return (x*x*x-3*x*x-6*x+8);
}
 
intBowRoot(a,b,h,eps,x,n,m)
doublea;                    /*实型变量,输入参数,求根区间的起始端点*/
doubleb;                    /*实型变量,输入参数,求根区间的终止端点*/
doubleh;                    /*利用逐步扫描法确定根位置时的步长*/
doubleeps;                          /*实型变量,输入参数,控制精度的参数*/
double *x;                            /*实型一维数组,输出参数,存放计算得到的数组*/
intn;                                      /*输入参数,区间内方程根的个数的预估值*/
int *m;                                   /*输出参数,实际求得的根的个数*/
{
         doublez,z1,z2,y,y1,y2;
         *m = 0;
         z = a;
         y = Func(z);
         while(1)              /*无限循环,直到遇到return或者break语句*/
         {/*如果逐步扫描到求根区间的右端点或者得到的根的个数达到预估根的个数*/
                  if((z>b+h/2)||(*m==n)) 
                            return(1);
                  if(fabs(y)<eps)             /*如果当前根z对应的函数f(z)满足精度要求*/
                   {
                            *m+=1;
                            x[*m-1] = z;         /*将此时的z值赋值给x数组*/
                            z+=h/2;
                            y = Func(z);
                            continue;          /*结束本次循环,即跳过循环体中下面尚未执行
                                                                  的语句接着进行下一次是否执行循环的判定*/
                   }
        
                   z1 = z+h;                    /*逐步扫描中小区间的右端点*/
                   y1 = Func(z1);           /*小区间右端点对应的函数值*/
                  if(fabs(y1)<eps)    /*如果右端点恰好满足根的精度要求*/
                   {
                            *m+=1;
                            x[*m-1] = z1;
                            z = z1+h/2;
                            y = Func(z);
                            continue;
                   }
                  if(y*y1>0)                            /*如果对应根乘积大于零,说明该区间内没有根*/
                   {
                            y = y1;                           
                            z = z1;
                            continue;
                   }
                  while(1)                   /*如果本while循环执行,说明逐步扫描小区建zz1间有根*/
                   {
                            if(fabs(z1-z)<eps)                  /*如果满足精度要求*/
                            {
                                     *m+=1;
                                     x[*m-1]=(z1+z)/2;
                                     z = z1+h/2;
                                     y = Func(z);
                                     break;
                            }
 
                            y1 = Func(z1);                              /*弦截法公式*/
                            y = Func(z);
                            z2=z1-(y1/(y1-y))*(z1-z);
                            y2 = Func(z2);
 
                            if(fabs(y2)<eps)
                            {
                                     *m = *m+1;
                                     x[*m-1] = z2;
                                     z =z2+h/2;
                                     y = Func(z);
                                     break;
                            }
                            if(y*y2<0)                            /*如果乘积小于零,说明根在zz0之间*/
                            {
                                     z1 = z2;
                                     y1 = y2;
                            }
                            else                               /*否则根在z0z1之间*/
                            {
                                     z = z2;
                                     y = y2;
                            }
                   }
         }
}
 
原创粉丝点击