C# 牛顿法平方根迭代

C# 牛顿法平方根迭代,c#,algorithm,time-complexity,square-root,newtons-method,C#,Algorithm,Time Complexity,Square Root,Newtons Method,我从以下位置提取了此代码: //a-平方根的数字 //times—迭代次数 公共双Sqrt(双a,整数倍) { if(a0) x=x/2+a/(2*x); 返回x; } 一个数字的迭代次数(如果存在)的经验法则是什么?(例如,“使用n/2次迭代”。) 对于一个数字的迭代次数(如果存在的话),什么是好的经验法则 牛顿法具有二次收敛性,即在算法的每一步中,答案中的有效位数都是原来的两倍。因此,该算法在O(logd)时间内计算高达D位精度的平方根。因此,循环中的迭代次数将取决于预期的精度。因此,为了

我从以下位置提取了此代码:

//a-平方根的数字
//times—迭代次数
公共双Sqrt(双a,整数倍)
{
if(a<0)
抛出新异常(“不能sqrt负数”);
双x=1;
while(次-->0)
x=x/2+a/(2*x);
返回x;
}
一个数字的迭代次数(如果存在)的经验法则是什么?(例如,“使用n/2次迭代”。)

对于一个数字的迭代次数(如果存在的话),什么是好的经验法则

牛顿法具有二次收敛性,即在算法的每一步中,答案中的有效位数都是原来的两倍。因此,该算法在
O(logd)
时间内计算高达D位精度的平方根。因此,循环中的迭代次数将取决于预期的精度。因此,为了对结果的准确性进行细粒度的控制,可以在代码中添加一个检查,当估计值不在错误界限之外时返回答案

public double Sqrt(double a){
    if (a < 0)
        throw new Exception("Can not sqrt a negative number");
    double error = 0.00001;
    double x = 1;
    while (true){
        double val = x*x;
        if(abs(val-a) <= error)
             return x;
        x = x / 2 + a / (2 * x);
    }
}
公共双Sqrt(双a){
if(a<0)
抛出新异常(“不能sqrt负数”);
双误差=0.00001;
双x=1;
while(true){
双val=x*x;

if(abs(val-a)如果您希望在固定的迭代次数下获得有保证的相对精度,则准备迭代,方法是将
a
除以4,直到结果介于1/2和2之间。或者,如果从小于1的值开始,则将其相乘。记住分段的数量,因为

sqrt(a)=2^k*sqrt(4^(-k)*a)

需要将结果与相同数量的因子2相乘。然后减少的
a
的平方根的相对误差如下

3*(1/6)^(2^米)

根据

(x[m]-sqrt(a))/(x[m]+sqrt(a))=(1-sqrt(a))/(1+sqrt(a))^(2^m)


通过使用C数学库中的浮点指数访问函数、
frexp
ldexp
以及Java中双类中的类似方法,您可以以最快的速度提取和操作所需的4和2的幂。

wow!这是一个比我预期的好得多的答案!谢谢!!如果你不介意…你知道我使用双精度和浮点值是否会有区别吗?双精度比浮点值提供更多的精度数字。因此,要获得更准确的答案,请使用双精度数据类型。你可以看到更多信息。对于C,同样的问题#
public double Sqrt(double a){
    if (a < 0)
        throw new Exception("Can not sqrt a negative number");
    double error = 0.00001;
    double x = 1;
    while (true){
        double val = x*x;
        if(abs(val-a) <= error)
             return x;
        x = x / 2 + a / (2 * x);
    }
}