C++ 平方根函数错误
C++ Square Root Function Bug
我有一个计算整数平方根的 C++ 算法。该程序可以正常工作,但有一个缺陷。它无法计算小于 1 的数字的平方根。例如,它无法计算 .5 或 .9 或 .0000001 等的平方根,但在所有其他情况下都按计划工作。我设置了 X,所以它不允许负输入,但我仍然不明白为什么它不会 return 小于 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,然后修改流程以增加而不是减少下一个猜测。
添加一些调试输出。这将帮助您理解为什么程序在 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;
}
如果遵循the Newton-Raphson method,程序会收敛得更快。此外,无论 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;
}
在 x<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;
}
我有一个计算整数平方根的 C++ 算法。该程序可以正常工作,但有一个缺陷。它无法计算小于 1 的数字的平方根。例如,它无法计算 .5 或 .9 或 .0000001 等的平方根,但在所有其他情况下都按计划工作。我设置了 X,所以它不允许负输入,但我仍然不明白为什么它不会 return 小于 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,然后修改流程以增加而不是减少下一个猜测。
添加一些调试输出。这将帮助您理解为什么程序在 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;
}
如果遵循the Newton-Raphson method,程序会收敛得更快。此外,无论 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;
}
在 x<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;
}