C++ double 值在相乘时丢失精度?

标签 c++ algorithm

我正在尝试创建一个函数来求一个数的平方根。出于调试目的,它有打印当前变量值的指令。函数 squareRoot 接受两个参数,xt。然后它声明并初始化 nsn 是加或减的数量,每次使用减半。 s 被认为是当前的平方根。运行时,我可以清楚地看到 n 正在正确调整。但是,当前四位数字正确时,s 停止更改。我在 main() 中使用这个调用:

cout << squareRoot(1000, 10) << "\n";

这应该将 1000 的平方根打印到最接近的十分之一,但是发生了两件奇怪的事情:

  • 它不会停留在 31.6。
  • 它停在 4 位数!

关于为什么它停在四位数的我的理论是:在乘法中,s 失去了一些精度。这是真的?如果是这样,你能告诉我如何纠正它吗?如果不是,是什么原因造成的,我该如何纠正?

我已经尝试通过使用另一个变量 s1 来解决它,该变量将被乘以并检查。然后 s 将增加 n,并且 s1s 同步。这没有用,所以我回到原来的代码。

我的代码如下:

#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。

关于C++ double 值在相乘时丢失精度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3644807/

相关文章:

c++ - 嵌套列表(字符串 vector 的 vector )初始化失败

c++ - 在另一个线程接收的套接字上触发 EAGAIN

c++ - ||对比或关键字

c++ - Qt:有什么方法可以调用具有特定时间间隔的一系列插槽?

algorithm - 在单链表时间复杂度中查找节点

algorithm - 对公式已知的表面进行光线追踪的最有效方法是什么?

c++ - 为什么我不能运行具有特定文件名的 exe?

algorithm - 最小化和同时最小化差异

algorithm - 计算二进制矩阵中的所有路径

algorithm - 在缺少前导零后撤消错误排序