求解方程

求解方程:
#include < stdio . h >
#include <math. h >
#include < malloc . h >
#include <stdlib. h >
 
double Func ( double );
int BisectRoot ( double , double , double , double , double *, int , int *);
 
void main ()
{
         int i , n , m ;
         double a , 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 );                                           /* 释放内存空间 */
}
 
double Func ( double x )
{
         return ( sin ( x ));
}
 
int BisectRoot ( a , b , h , eps , x , n , m )
double a ;                    /* 实型变量,输入参数,求根区间的起始端点 */
double b ;                    /* 实型变量,输入参数,求根区间的终止端点 */
double h ;                    /* 利用逐步扫描法确定根位置时的步长 */
double eps ;                          /* 实型变量,输入参数,控制精度的参数 */
double * x ;                            /* 实型一维数组,输出参数,存放计算得到的数组 */
int n ;                                      /* 输入参数,区间内方程根的个数的预估值 */
int * m ;                                   /* 输出参数,实际求得的根的个数 */
{
         double z , 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 循环执行,说明逐步扫描小区建 z z1 间有根 */
                   {
                            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)                            /* 如果乘积小于零,说明根在 z z0 之间 */
                            {
                                     z1 = z0 ;
                                     y1 = y0 ;
                            }
                            else                              /* 否则根在 z0 z1 之间 */
                            {
                                     z = z0 ;
                                     y = y0 ;
                            }
                   }
         }
}

牛顿迭代法:
#include < stdio .h>
#include <math.h>
#include <stdlib.h>
 
int Function ( double , double *, double *);
int Newton ( double *, double , int );
 
int Function ( x , f , dy )
double x ;
double * f ;
double * dy ;
{
         * f = x * x *( x -1)-1;
         * dy = 3* x * x -2* x ;
         return (1);
}
 
int Newton ( x , eps , l )
double * x ;
double eps ;
int l ;
{
         double f , 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);
                   goto A ;
         }
         * x = x1 ;
         return 1;
}
 
void main ()
{
         double x , eps ;
         int l ;
         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 >
 
double Func ( double );
int BowRoot ( double , double , double , double , double *, int , int *);
 
void main ()
{
         int i , n , m ;
         double a , 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 );                                           /* 释放内存空间 */
}
 
double Func ( double x )
{
         return ( x * x * x -3* x * x -6* x +8);
}
 
int BowRoot ( a , b , h , eps , x , n , m )
double a ;                    /* 实型变量,输入参数,求根区间的起始端点 */
double b ;                    /* 实型变量,输入参数,求根区间的终止端点 */
double h ;                    /* 利用逐步扫描法确定根位置时的步长 */
double eps ;                          /* 实型变量,输入参数,控制精度的参数 */
double * x ;                            /* 实型一维数组,输出参数,存放计算得到的数组 */
int n ;                                      /* 输入参数,区间内方程根的个数的预估值 */
int * m ;                                   /* 输出参数,实际求得的根的个数 */
{
         double z , 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 循环执行,说明逐步扫描小区建 z z1 间有根 */
                   {
                            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)                            /* 如果乘积小于零,说明根在 z z0 之间 */
                            {
                                     z1 = z2 ;
                                     y1 = y2 ;
                            }
                            else                                /* 否则根在 z0 z1 之间 */
                            {
                                     z = z2 ;
                                     y = y2 ;
                            }
                   }
         }
}
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值