[英]C++ double value losing precision when multiplied?
我正在尝试创建一个函数来查找数字的平方根。 出于调试目的,它具有打印当前变量值的指令。 函数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。 提前感谢您的所有答案!
它收敛到正确的平方根,但cout默认只打印六位有效数字:31.xxxx。
另请注意,您的终止检查不起作用,因为对于t> 1,(1 / t)将始终评估为0。 请改用1./t。
原因循环没有停止是循环条件不正确。 你有
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
。
不相关,但您的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);
}
牛顿方法也适用于立方根等。对于十进制指数,查找二项式定理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.