【问题标题】:Finding square root of 2 upto more than 100 decimal places求 2 的平方根到小数点后 100 位以上
【发布时间】:2012-01-20 06:44:31
【问题描述】:

我试图通过使用牛顿方法来完成这项工作,如下所述:wiki 使用以下代码,但问题是它只能给出精确到小数点后 16 位的结果。我试图增加迭代次数,结果还是一样。我从 1 的初始猜测开始。那么我怎样才能提高答案的准确性(最多 100 位或更多小数位)? 谢谢。 代码:

double x0,x1;
#define n 2
double f(double x0)
{
    return ((x0*x0)-n);
}
double firstDerv(double x0)
{
    return 2.0*x0;
}
int main()
{
    x0 = n/2.0;
    int i;
    for(i=0;i<40000;i++)
    {
        x1=x0-(f(x0)/((firstDerv(x0))));
        x0=x1;
    }
    printf("%.100lf\n",x1);
    return 0;
}

【问题讨论】:

标签: math square-root newtons-method


【解决方案1】:

当前机器上的浮点数是IEEE754,并且精度有限(大约 15 位)。

如果您想要更高的精度,您将需要 bignums,它们(缓慢)由软件库(如 GMP)提供

您还可以使用 bignums 以语言和实现对您的程序进行编码。

【讨论】:

  • 谢谢,我在 python 中尝试过,但我也无法获得如此高的准确度,尽管它比 c 中的要高
  • 至少对于整数 bignums,SBCL 和 SciLab 应该有它们。 (我不知道浮动 bignums)。
【解决方案2】:

你根本无法用这种方法做到这一点;双打没有足够的位来获得 100 位精度。考虑使用任意精度的库,例如 GMP

【讨论】:

    【解决方案3】:

    这可能是因为浮点数是由计算机通过 m*10^e 形式近似的。由于 m 和 e 由有限数量的数字组成,因此您无法以绝对精度逼近所有数字。

    想想 1/3 是 0.333333333333333...

    【讨论】:

    • 大多数浮点表示都是二进制的,所以m*2^e的形式使用你的符号(即基数2,而不是基数10)
    【解决方案4】:

    为了解决浮点精度有限的问题,还可以使用牛顿法 在每次迭代中找到一个有理数(a/b,具有 a 和 b 整数),它是 sqr(2) 的更好近似值。

    如果 x=a/b 是您上次迭代返回的值,则牛顿法表明新的估计 y=c/d 是:

    y = x/2 + 1/x = a/2b + b/a = (a^2+2b^2)(2ab)

    所以:

    c= a^2 + 2b^2

    d=2ab

    每次迭代精度加倍。您仍然可以达到的精度有限,因为 nominator 和 denominator 迅速增加,但也许找到大整数的实现(或自己编造一个)比找到任意精度浮点的实现更容易。另外,如果您真的对小数感兴趣,那么这个答案对您没有帮助。它确实为您提供了一个非常精确的 sqr(2) 估计值。

    只是算法的一些 a/b 迭代:

    1/1、3/2、17/12、577/408、665857/470832。

    665857/470832 近似于 sqr(2),误差为 1.59e-12。错误将保持为 1/a^2 的顺序,因此实现 a 和 b as longs 将为您提供 1e-37 -ish 的精度。

    【讨论】:

    • +1 用于建议有理算术方法。如果想避免使用任意精度的浮点库,我可以想象编写一个长除法例程,一次输出一个十进制数字。当然,在某些时候,即使是 64 位整数也不能满足要求。那些会给出你建议的大约 1e-37 精度(作为一个合理的对),并且 OP 想要远远超出这个范围。所以也许using GMP 仅仅因为它的多精度整数是一个快乐的媒介。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多