二分法平方根计算的问题
Issues with bisection method square root calculation
#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 的数字的平方根大于初始数字(记住 root 函数)。由于 userNum
是可能结果的上限,因此无法使用您的代码计算这些根。
作为解决方案:添加
if( userNum < 1.0 ) {
upper = 1.0;
}
在循环前面。
解决问题的另一部分:mid
实际上由真根和错误 组成。在 fabs
部分,您将两者平方。因此,您实际上将 errorVal
与 进行比较,最后您只打印 .
进行比较
#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 的数字的平方根大于初始数字(记住 root 函数)。由于 userNum
是可能结果的上限,因此无法使用您的代码计算这些根。
作为解决方案:添加
if( userNum < 1.0 ) {
upper = 1.0;
}
在循环前面。
解决问题的另一部分:mid
实际上由真根和错误 组成。在 fabs
部分,您将两者平方。因此,您实际上将 errorVal
与 进行比较,最后您只打印 .