二分法平方根计算的问题

时间:2017-08-05 13:43:36

标签: c++ square-root bisection

#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
double bisection(double errorVal, double userNum){
    double upper=userNum, lower=0;
    double mid=(lower+upper)/2.0;
    while(!(fabs(mid*mid-userNum)<=errorVal)){
        mid=(lower+upper)/2.0;
        if(mid*mid>userNum){
            upper=mid;
        }else{
            lower=mid;
        }
    }
    return mid;
}

int main(){
    double errorVal=0, userNum=0;
    std::cout<<"Please enter a number (larger than 0) to calculate its square root, and the desired margin of error."<<std::endl;
    std::cin>>userNum>>errorVal;
    bisection(errorVal,userNum);
    std::cout<<"The calculated result is "<<std::setprecision(11)<<bisection(errorVal,userNum)<<". The amount of error is "<<fabs(bisection(errorVal, userNum)-sqrt(userNum))<<"."<<std::endl;
}

这是一个原型程序,我设计用于计算用户输入确定的数字的平方根,使用二分法(我知道有更好的方法,如Newton-Raphson,CORDIC,但这是给出的赋值)。

唯一的问题如下:

userNum的输入是从0到1的小数时,无论指定的精度是多少,程序都会停止,输入0.1,0.1会有明显的例外。这会产生0.5的不准确结果,误差为0.266227766,高于0.1的指定误差范围。

我的主要问题是,为什么不处理0到1之间的数字?

1 个答案:

答案 0 :(得分:1)

小于1的数字的平方根比初始数大(记住根函数)。由于userNum是可能结果的上限,因此无法使用您的代码计算这些根。 作为解决方案:添加

if( userNum < 1.0 ) {
  upper = 1.0;
}

在循环前面。

要解决问题的其他部分:mid实际上由真根和错误(\Delta mid)^2 + 2 mid * \Delta mid组成。在fabs - 部分中,你将两者都对齐。因此,您实际上将errorValmid + \Delta mid进行了比较,最后打印以进行比较enter image description here