問題

2017-08-05 11 views
0
#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; 
} 

これは私がユーザ入力によって決定された数の平方根を計算するように設計されたプロトタイプのプログラムでは、二分法を使用して(私は、このようなニュートン・ラプソンとしてより良い方法がある知りますCORDIC、これは与えられた課題です)。問題

左唯一の問題は、次の通りである:

userNumの入力が0から1に小数であり、プログラムストール関係なく指定された精度は、0.1、0.1を入力するの注目すべき例外であるもの。これは0.5の不正確な結果をもたらし、誤差は0.266227766であり、これは指定された誤差マージン0.1を上回っている。

私の主な質問は、なぜ0と1の間の数字を処理しないのですか?

+0

あなたのuserprecisionは二乗された値になります。そしてそれを二乗根の誤差と比較します。普通は同じではありません –

+0

ああ、私の心が崩れました。今、大きな問題は...私はそれが0から1までの数字を与えるとき、それはなぜバグですか?この行の –

+0

: 場合(ミッド*中旬> userNum){ あなたの値は0と1の間にある場合、条件が乗根として<なければなりませんが>入力には、私は 'codeblocks'タグを削除 –

答えて

1

1より小さい数の平方根は、最初の数よりも大きくなります(ルート関数を覚えておいてください)。可能な結果の上限はuserNumなので、それらのルートはコードでは計算できません。 解決策として:ループの前に、

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

を追加します。

質問の残りの部分をアドレス指定するにはmidは実際には真のルートとエラーmid + \Delta midで構成されます。 fabs -partでは、両方を正方形にします。したがって、実際にはerrorVal(\Delta mid)^2 + 2 mid * \Delta midを比較し、最後には比較のために印刷するだけでmid + \Delta midとなります。