Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2124063
  • 博文数量: 288
  • 博客积分: 10594
  • 博客等级: 上将
  • 技术积分: 3469
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-27 19:27
文章分类

全部博文(288)

文章存档

2012年(4)

2011年(30)

2010年(40)

2009年(32)

2008年(71)

2007年(79)

2006年(32)

分类: C/C++

2007-03-29 16:25:57

算法:
  要计算 ,相当于求方程:
    
的正实根。解决这个问题,我们可以使用牛顿迭代公式。
  对于一般的线性方程 ,用牛顿迭代法求解的方法是:给定一个初值,用下面的迭代公式:
    
得到一个迭代序列,当 (给定的精度)时,我们便认为 为方程 的根,并停止迭代。
  牛顿迭代法有很明显的几何意义(参见右图5-12),当我们选定 以后,过 的切线,其切线方程为:
    
求此切线方程与x轴的交点,即得:
    
正因为牛顿法有这一明显得几何意义,所以也叫切线法。
图示 图5-12
 
  本题中,因为 ,故牛顿迭代公式为:
    
在区间(0, ∞)内 单调增大, ,因此,对于任取的 都收敛于s。
 
 
程序:
  根据上面的算法,我们可以编出计算一个正数的、n次方的、正实根的函数NewtonRoot,也编写一个main函数,就得到一个完整的程序如下:
例题 例5-29
  #include
#include
#include
const double SMALLFRACTION = 1.0E-8;

double NewtRoot(double x, int n)
{
 double x0, x1, f0, f1;
 assert(x > 0.0);
 x0 = x / 2.0;x1 =x;
 while(fabs(x1-x0) > SMALLFRACTION*x1) {
  cout << r << endl;
  x0 = x1;
  f0 = pow(x0, n) - x;
  f1 = n*pow(x0, n-1) - x0;
  x1 = x0 - f0/f1;
 }
return x1;
}

void main()
{
 double x;
 int n;
 cout << "Enter number : ";
 cin >> x;
 cout << "\nEnter exponent : ";
 cin >> n;
 cout << "Number was : " << x << ", root is "
 << NewtRoot (x, n) << endl;
}
  在上面的程序中,我们定义了一个double型全局常量SMALLFRACTION,它是给定的计算精度。也就是说,迭代出的近似解必须满足该精度要求(10-8)。
  NewtRoot函数有两个形参x和n,分别是待求方根的正实数及方根次数。定义了4个double型变量:x1、x0、f0和f1,分别表示:当前迭代值、前一次迭代值、前一次迭代值的函数值和前一次迭代值的函数的一阶导数值。x0的初值取形参x,x1的初始值取形参x的一半。
  NewtRoot函数中用到了几个C++库函数:assert、fabs和pow。assert函数在assert.h中定义,其功能是:若形参表达式为假,则打印诊断信息,并停止应用程序的运行。fabs和pow在math.h中定义,分别是求一个double型数的绝对值与乘方。
  在main函数中,分别输入待求方根的正实数及方根次数,然后调用NewtRoot,并输出计算结果。
  假定编译、运行该程序,并输入:
  Enter number : 2↙
  Enter exponent : 2↙
  输出结果如下:
  1
  1.5
  1.41667
  1.41422
  1. 41421
为了掌握函数的用法,我们再举两个函数应用的例子。第一个例子是关于有缺省参数的函数的用法:
例题 例5-30
 

// 有缺省参数的函数
#include
#include
void de_fun(int i=5, long j=40034, float x=10.25,
char ch='Z', double d=4.3234); // 函数原型

void main()
{
 de_fun(); // 使用所有的缺省参数
 de_fun(2); // 覆盖第一个缺省参数
 de_fun(2, 75037); // 覆盖第一和第二个缺省参数
 de_fun(2, 75037, 35.88); // 覆盖第一、第二和第三个缺省参数
 de_fun(2, 75037, 35.88, 'G'); //覆盖第一、第二、第三和第四个缺省参数
 de_fun(2, 75037, 35.88, 'G', .0023); // 未使用缺省参数
}

void de_fun(int i, long j, float x, char ch, double d)
{
 cout << setprecision(4) << "i: " << i << " " << "j: " << j;
 cout << " x: " << x << " " << "ch: " << ch;
 cout << " d: " << d << "\n";
 return;
}

  上述程序的运行结果如下:
  i: 5 j: 40034 x: 10.25 ch: Z d: 4.3234
  i: 2 j: 40034 x: 10.25 ch: Z d: 4.3234
  i: 2 j: 75037 x: 10.25 ch: Z d: 4.3234
  i: 2 j: 75037 x: 35.88 ch: Z d: 4.3234
  i: 2 j: 75037 x: 35.88 ch: G d: 4.3234
  i: 2 j: 75037 x: 35.88 ch: G d: 0.0023
  对de_fun()的每一次调用都产生了不同的结果,这是因为:在main函数中,每一次调用de_fun()均传送了不同的实参。


下面再看一个函数重载的例子,函数名为abs,其功能为求一个数的绝对值:
例题 例5-31
 

// 重载两个绝对值函数.
#include
#include
int abs(int i); // abs()重载三次
float abs(float x);
float abs(double x);

void main()
{
 int ians; // 保存返回值
 float fans;
 double dans;
 int i = -15; // 传到三个重载的函数
 float x = -64.53;
 double d = -120.293;
 ians = abs(i); // C++调用整数abs()
 cout << "整数-15的绝对值是 " << ians << "\n";
 fans = abs(x); // C++调用单精度浮点abs()
 cout << "单精度浮点-64.53的绝对值是 " <<
 setprecision(4) << fans << "\n";
 dans = abs(d); // C++调用双精度浮点abs()
 cout << "双精度浮点-120.293的绝对值是 " <<
 setprecision(6) << dans << "\n";
 // 根据参数的类型,C++匹配有合适参数的函数
}

int abs(int i) // 整型绝对值函数
{
 if (i < 0)
  return i *( -1);
 else
 return i;
}

float abs(float x) // 单精度浮点绝对值函数
{
if (x < 0.0)
 return x * (-1.0);
else
return x;
}

double abs(double x) // 双精度浮点绝对值函数
{
if (x < 0.0)
 return x * (-1.0);
else
return x;
}

  运行该程序,输出结果如下:
  整数-15的绝对值是15
  单精度浮点-64.53的绝对值是64.53
  双精度浮点-120.293的绝对值是120.293

阅读(6778) | 评论(0) | 转发(1) |
0

上一篇:函数的递归调用与分治策略

下一篇:逐恶

给主人留下些什么吧!~~