1

我试图通过使用此处描述的牛顿方法来完成这项工作: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;
}
4

4 回答 4

4

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

如果 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

每次迭代精度加倍。您仍然可以达到的精度有限,因为提名和分母迅速增加,但也许找到大整数的实现(或自己炮制一个)比找到任意精度浮点的实现更容易。此外,如果您真的对小数感兴趣,那么这个答案对您没有帮助。它确实为您提供了一个非常精确的 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 的精度。

于 2011-12-14T14:59:55.703 回答
2

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

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

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

于 2011-12-14T13:40:45.230 回答
2

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

于 2011-12-14T13:41:39.097 回答
0

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

想想 1/3 是 0.333333333333333 ......

于 2011-12-14T13:41:40.083 回答