У меня есть алгоритм C ++, который вычисляет квадратный корень из целого числа. Программа работает за исключением одного недостатка. Он не может вычислить квадратный корень числа, которое меньше 1. Например, он не может вычислить квадратный корень из .5 или .9 или .0000001 и т. Д., Но работает как запланировано для всех других ситуаций. Я установил X, поэтому он не допускает отрицательный ввод, но я все еще не понимаю, почему он не будет возвращать значение для чего-либо меньше 1.
include <iostream>
#include <cmath>
#include <cassert>
using namespace std;
double squareroot(double x)
{ /* computes the square root of x */
/* make sure x is not negative .. no math crimes allowed! */
assert(x >= 0);
if (x == 0) return 0;
/* the sqrt must be between xhi and xlo */
double xhi = x;
double xlo = 0;
double guess = x / 2;
/* We stop when guess*guess-x is very small */
while (abs(guess*guess - x) > 0.000001)
{
if (guess*guess > x) xhi = guess;
else xlo = guess;
guess = (xhi + xlo) / 2;
}
return guess;
}
/* Test Stub */int main()
{
double testvalue;
cout << "\n Enter a TestValue= ";
cin >> testvalue;
cout << endl;
double testresult = squareroot(testvalue);
cout << "\n Square Root= " << testresult << "\n";
}
Спасибо за помощь! Я смог решить проблему с помощью следующего:
if (x<1) {
xhi = 1;
xlo = x;
guess = (x + 1) / 2;
}
Квадратный корень из 0,5 составляет ~ 0,7. Ваша логика предполагает угадывание меньшего числа, если проверка не удалась. Что вам нужно сделать, это добавить дополнительный слой обнаружения, чтобы увидеть, если число < 1, а затем измените поток, чтобы увеличить следующее предположение, а не уменьшать его.
В случае х<1 вам нужно изменить начальные границы, потому что квадратный корень расположен не между 0 и x, а между x и 1
double xhi, xlo, guess;
if (x > 1){
xhi = x;
xlo = 0;
guess = x / 2;
}
else{
xhi = 1;
xlo = x;
guess = (x + 1) / 2;
}
Добавьте отладочный вывод. Это поможет вам понять, почему программа никогда не сходится к решению, когда x < 1.0
,
while (abs(guess*guess - x) > 0.000001)
{
if (guess*guess > x)
{
cout << "Changing xhi\n";
xhi = guess;
}
else
{
cout << "Changing xlo\n";
xlo = guess;
}
guess = (xhi + xlo) / 2;
cout << "guess: " << guess << endl;
}
Если вы будете следовать метод Ньютона-Рафсона, программа будет сходиться быстрее. Кроме того, он работает независимо от того, x
больше или меньше 1.
double squareroot(double x)
{
/* make sure x is not negative .. no math crimes allowed! */
assert(x >= 0);
if (x == 0) return 0;
double guess = x / 2;
while (abs(guess*guess - x) > 0.000001)
{
double dx = 0.5*(guess*guess -x)/guess;
guess -= dx;
cout << "guess: " << guess << endl;
}
return guess;
}