在 C 中使用二分法的两个根之间的区别?
Difference between two roots using bisection method in C?
我写了这段 C 代码来比较两个函数的根,使用二分法。我的第一个函数 (g(x)) 执行正确,但第二个函数 (h(x)) 在屏幕上输出“#1QO”。我在代码中找不到我做错了什么。
你能解释一下吗?
任何形式的帮助将不胜感激。谢谢!
#include <stdio.h>
#include <math.h>
typedef double (*DFD) (double);
double g (double x)
{
double y;
y = pow (x,3) - pow (x,2)-1;
return y;
}
double h (double x)
{
double k;
k = 1.0 + (1.0/x) + (1.0 /pow (x,2));
return k;
}
double bisection (DFD f, double x0, double x1,double tol)
{
int i;
double middle;
for (i=1;i<=50;) {
middle = (x0+x1)/2.0;
if (fabs (middle - x0) <tol) return middle;
if (f(middle)* f(x0) <0.0) x1 = middle;
else x0 = middle;
}
}
int main () {
double root_gx, root_hx = 0.0;
root_gx = bisection (g,0,2,0.0005);
printf ("Root found using g(x) = %.3lf\n",root_gx);
root_hx = bisection (h,1,2,0.0005);
printf ("Root found using h(x) = %.3lf\n",root_hx);
printf ("Difference between the two roots = %.3lf\n", (fabs (root_gx- root_hx)));
return 0;
}
编辑:在二等分中初始化 i=1 并将 bisection (h,0,2,0.0005)
更改为 bisection (h,1,2,0.0005)
并且有效 谢谢大家!
double h (double x)
{
double k;
k = 1.0 + (1.0/x) + (1.0 /pow (x,2));
return k;
}
如果 x==0.0
则除以零。当您调用 bisection (h,0,2,0.0005);
时执行此操作,它调用 f(x0)
,在本例中为 h(0.0);
。
如果你在一个函数中除以一个输入参数,那么你应该经常检查输入参数的实际值是否不等于0.0
:
double h (double x)
{
if ( x == 0.0 ) return 1e99; // infinite
double k;
k = 1.0 + (1.0/x) + (1.0 /pow (x,2));
return k;
}
值未初始化导致未定义的行为。设置为某个值。
// int i;
int i = 0;
...
for (;i<=50;) {
i
永远不会递增。
50
是任意的。
建议使用 double
的二进制精度,因为 bisection()
每次迭代减半。
for (i=0; i <= DBL_MANT_DIG; i++) {
...
}
return middle;
还建议更改算法以允许更改 |difference| 0.0 以满足公差 0.0.
// if (fabs (middle - x0) <tol) return middle;
if (fabs (middle - x0) <= tol) return middle;
我写了这段 C 代码来比较两个函数的根,使用二分法。我的第一个函数 (g(x)) 执行正确,但第二个函数 (h(x)) 在屏幕上输出“#1QO”。我在代码中找不到我做错了什么。
你能解释一下吗? 任何形式的帮助将不胜感激。谢谢!
#include <stdio.h>
#include <math.h>
typedef double (*DFD) (double);
double g (double x)
{
double y;
y = pow (x,3) - pow (x,2)-1;
return y;
}
double h (double x)
{
double k;
k = 1.0 + (1.0/x) + (1.0 /pow (x,2));
return k;
}
double bisection (DFD f, double x0, double x1,double tol)
{
int i;
double middle;
for (i=1;i<=50;) {
middle = (x0+x1)/2.0;
if (fabs (middle - x0) <tol) return middle;
if (f(middle)* f(x0) <0.0) x1 = middle;
else x0 = middle;
}
}
int main () {
double root_gx, root_hx = 0.0;
root_gx = bisection (g,0,2,0.0005);
printf ("Root found using g(x) = %.3lf\n",root_gx);
root_hx = bisection (h,1,2,0.0005);
printf ("Root found using h(x) = %.3lf\n",root_hx);
printf ("Difference between the two roots = %.3lf\n", (fabs (root_gx- root_hx)));
return 0;
}
编辑:在二等分中初始化 i=1 并将 bisection (h,0,2,0.0005)
更改为 bisection (h,1,2,0.0005)
并且有效 谢谢大家!
double h (double x)
{
double k;
k = 1.0 + (1.0/x) + (1.0 /pow (x,2));
return k;
}
如果 x==0.0
则除以零。当您调用 bisection (h,0,2,0.0005);
时执行此操作,它调用 f(x0)
,在本例中为 h(0.0);
。
如果你在一个函数中除以一个输入参数,那么你应该经常检查输入参数的实际值是否不等于0.0
:
double h (double x)
{
if ( x == 0.0 ) return 1e99; // infinite
double k;
k = 1.0 + (1.0/x) + (1.0 /pow (x,2));
return k;
}
值未初始化导致未定义的行为。设置为某个值。
// int i;
int i = 0;
...
for (;i<=50;) {
i
永远不会递增。
50
是任意的。
建议使用 double
的二进制精度,因为 bisection()
每次迭代减半。
for (i=0; i <= DBL_MANT_DIG; i++) {
...
}
return middle;
还建议更改算法以允许更改 |difference| 0.0 以满足公差 0.0.
// if (fabs (middle - x0) <tol) return middle;
if (fabs (middle - x0) <= tol) return middle;