计算方法-C语言二分法求根

问题:

给出方程f(x) = x^3+10x-20,求该方程在(1,2)上的根,其精度不小于10^-4

看似很简单的一个小问题,其实有很有细节值得注意,先给出代码

方法一:

#include <stdio.h>
#include <math.h>

double f(double x)
{
    return x*x*x+10*x-20;
}

int main()
{
    double l,r,mid,ans;
    l = 1;
    r = 2;
    while(1) {
        mid = (l+r)/2;
        double cnt = f(mid);
        if(fabs(cnt) <= 0.0001) {
            ans = mid;
            printf("%lf\n",cnt);
            break;
        }
        if(cnt > 0) r = mid;
        else l = mid;
    }
    printf("%.4lf\n",ans);
    return 0;
} 

方法二:

#include <stdio.h>
#include <math.h>

double ans;

double f(double x)
{
    return x*x*x+10*x-20;
}

void m(double l,double r)
{
    double mid = (l+r)/2;
    double cnt = f(mid);
    if(fabs(cnt) <= 1e-4) {
        ans = mid;
        return ;
    }
    if(cnt > 0) m(l,mid);
    else m(mid,r);
}

int main()
{
    m(1,2);
    printf("%.4lf\n",ans);
    return 0;
} 

两种方法没有本质上的区别,算法实质是一样的,只是在程序实现手段上稍有不同,方法一用的循环,而方法二用的递归。

有这么几点需要注意

(1)如何确定精度小于1e-4

首先我们要想明白,我们要确定的是“根”的精度,即让f(ans)=0的那个ans的计算值和真理值得差不大于1e-4,我们不知道所谓的真理值是多少,但是我们能确认他的函数值,即0,因此这个问题就转化成了我们计算得到的值ans的函数值f(ans)与0的绝对值差要不大于1e-4,因而我们就可以每次求出当前的mid即可能中点的值,看看他与0的差距是否小于等于1e-4,如果是,这个mid就是我们最终要求的结果。

(2)关于每次迭代l和r的值的确定,暂时没有发现什么一般性的规则,只是在这道题中,我们可以用图像很直观的表达出来l和r的更替规律

首先很容易可以求出f(x)在定义域上为单调递增,然后在x=1的值是负的,在x=2的值是正的,那么二者之间就必然只有一个根了,因此如果当前求得的f(ans)的值为正数和负数的情况,根据该图,我们都能很清晰的看出来到底该把谁给赋值。

时间: 2024-08-30 10:17:30

计算方法-C语言二分法求根的相关文章

链表实现二分法求根

#include<iostream>#include<iomanip>#include<cmath>using namespace std;class poly{public: double c; int e; poly*next;};poly*input();double f(poly*head,double x);double root(poly*head,double a, double b);int main(){ poly*head; double a, b;

(四) 二分法求根

1 # -*- coding: utf-8 -*- 2 #coding=utf-8 3 import numpy as np 4 import matplotlib.pyplot as plt 5 6 7 8 plt.close() 9 fig = plt.figure() 10 plt.grid(True) 11 plt.axis([0,2, -2, 5]) 12 plt.ion() 13 plt.xlabel("X") 14 plt.ylabel("Y") 15

二分法求根

1 #include<stdio.h> 2 #include<math.h> 3 float f(float x){ 4 return (x*x*x-x-1); 5 } 6 int main(){ 7 float x1, x2; 8 scanf("%f,%f", &x1, &x2); 9 10 float cen=(x1+x2)/2.0; 11 float vc=f(cen); 12 while(fabs(vc) > 1e-6){ 13 1

二分法求三次方程的根

二分法求根 #include "stdio.h" #define f(x) a*x*x*x+b*x*x+c*x+d int main() { freopen("in.txt", "r", stdin); int a, b, c, d; double x1, x2, x, y1, y2, y; while (scanf("%d%d%d%d", &a, &b, &c, &d) != EOF) { x

方程求根——二分法

二分法求根主要应用了区间套定理,这一算法实现简单且结果也迭代的较好,但对于复杂函数其结果不理想 1.代码 %%二分法求根 %%f为函数表达式,interval0为初始区间,epsilon为控制精度 function RD = Roots_dichotomy(f,interval0,epsilon) x_low = interval0(1);x_up = interval0(2);x_ave = (x_low+x_up)/2; %%作图 t = x_low:(x_up-x_low)/1000:x_

Openjudge ch0111/t6253 用二分法求方程的根

这题只是考你最后有没有(r-l)/2而已…… 总时间限制: 1000ms 内存限制: 65536kB 描述 用二分法求下面方程在(-10, 10)之间的一个根. 2x3- 4x2+ 3x- 6 = 0 输入 一个小于1的非负实数e,它的值表示所能允许的误差 输出 一个实数,其值为求得的一个根,要求精确到小数点后8位.若该区间上没有根,则输出“No Solution” 样例输入 0 样例输出 2.00000000 提示 对于一个连续函数f(x),若f(a)*f(b) <= 0,则f(x)在区间[a

R语言求根

求根是数值计算的一个基本问题,一般采用的都是迭代算法求解,主要有不动点迭代法.牛顿-拉富生算法.割线法和二分法. 不动点迭代法 所谓的不动点是指x=f(x)的那些点,而所谓的不懂点迭代法是指将原方程化为x=f(x)形式之后,下一步所用的x值为这一步的f(x),这样的话就可以一直逼近我们需         要的x,即方程的根,但是这种方法可能不会收敛到方程的根,随着初始值选定的大小,可能会有发散的情况,因此需要谨慎使用. ###不动点迭代法 func1 <- function(x){return(

用二分法求下面方程在(-10,10)之间的根。【谭浩强第四版课后习题】

用二分法求下面方程在(-10,10)之间的根:2x3-4x2+3x-6=0 编程思路:仿照二分查找,将区间划分为两部分,记录区间左右端点,得到中点.每次运算将中点带入方程: 结果>0:根应该向小一点的值拟合,high=mid; 结果<0:根应该向大一点的值拟合,low=mid; 对于跳出循环的条件,我首先是认为low和high应该无限逼近:while(fabs(low-high)>1e-5),当循环体内结果=0后,便使用break跳出循环:if(temp==0) break;但是没有得到

03-1. 二分法求多项式单根

二分法求函数根的原理为:如果连续函数f(x)在区间[a, b]的两个端点取值异号,即f(a)f(b)<0,则它在这个区间内至少存在1个根r,即f(r)=0. 二分法的步骤为: 检查区间长度,如果小于给定阈值,则停止,输出区间中点(a+b)/2:否则 如果f(a)f(b)<0,则计算中点的值f((a+b)/2): 如果f((a+b)/2)正好为0,则(a+b)/2就是要求的根:否则 如果f((a+b)/2)与f(a)同号,则说明根在区间[(a+b)/2, b],令a=(a+b)/2,重复循环: