我正在尝试创建一个函数来查找数字的平方根。出于调试目的,它具有打印当前变量值的指令。函数squareRoot
接受两个参数x
和t
。然后它声明并初始化n
和s
。 n
是要添加或减去的数量,每次使用时减半。 s
被认为是当前的平方根。运行时,我可以清楚地看到n
正在正确调整。但是,当前四位数字正确时,s
会停止更改。我在main()
中使用此电话:
cout << squareRoot(1000, 10) << "\n";
这应该将1000的平方根打印到最接近的十分之一,但会发生两件奇怪的事情:
关于它为什么停在四位数的理论是这样的:在乘法中,s
会失去一些精度。这是真的?如果是这样,你能告诉我如何纠正它吗?如果不是,导致这种情况的原因以及如何纠正?
我尝试使用另一个变量s1
来解决它,它将被乘以并检查。然后s
将增加n
,s1
将与s
同步。这没用,所以我回到了原始代码。
我的代码如下:
#include <iostream>
using namespace std;
double squareRoot(double x, int t) {
double s = 0;
double n = 0.1;
while ((s*s) <= x) {
s += n;
n *= 2;
cout << n << "\n" << s << "\n";
}
cout << "\n";
s -= n;
// Keep changing until margin of error is reached
while ((((s*s) - x) < (1/t)) || ((x - (s*s) < (1/t)))) {
// If too high, lower s
if ((s*s) <= x) {
s += n;
n /= 2;
cout << "Adding 1/2 of previous n\n";
}
// If too low, raise s
else if ((s*s) >= x) {
s -= n;
n /= 2;
cout << "Subtracting 1/2 of previous n\n";
}
cout << s << "\n" << n << "\n\n";
}
return s;
}
我正在运行Windows 7 64位,MSVC ++ 2008 Express。提前感谢您的所有答案!
答案 0 :(得分:2)
它收敛到正确的平方根,但cout默认只打印六位有效数字:31.xxxx。
另请注意,您的终止检查不起作用,因为对于t> 1,(1 / t)将始终评估为0。请改用1./t。
答案 1 :(得分:1)
原因循环没有停止是循环条件不正确。
while ((current - target < precision) || (target - current < precision)) {
...
}
但值current - target
或值target - current
将为<= 0
。并0 < precision
。因此,你有相当于while (true) {...}
循环
你需要像
while (abs(current - target) > precision) {
...
}
(不知道在C ++中获取绝对值的确切函数)
修改强>
刚刚注意到, hamster3null 在我面前写了1/t
。
答案 2 :(得分:1)
不相关,但您的sqrt算法可以通过使用现有算法加速,例如Newton's Method。
它是这样的:
double mySqrt(double x, unsigned long accuracy = 10)
{
if(x < 0.0)
return(-1.0);
double retval = 1.0;
for(unsigned long rep = 0; rep < accuracy; rep++)
retval = ((x / retval) + retval) / 2.0;
return(retval);
}
牛顿方法也适用于立方根等。 对于十进制指数,请查找二项式定理。