有一个更好的算法,最多需要6次迭代才能收敛到双精度的最大精度:
#include <math.h>double sqrt(double x) { if (x <= 0) return 0; // if negative number throw an exception? int exp = 0; x = frexp(x, &exp); // extract binary exponent from x if (exp & 1) { // we want exponent to be even exp--; x *= 2; } double y = (1+x)/2; // first approximation double z = 0; while (y != z) { // yes, we CAN compare doubles here! z = y; y = (y + x/y) / 2; } return ldexp(y, exp/2); // multiply answer by 2^(exp/2)}
算法从1开始,作为平方根值的一阶近似值。然后,在每个步骤上,通过取当前值
y和之间的平均值来改善下一个近似
x/y。如果
y=
sqrt(x),则将相同。如果
y>
sqrt(x),则
x/y<
sqrt(x)大约相等。换句话说,它将很快收敛。
更新 :为加快非常大或非常小的数字的收敛,更改了
sqrt()函数以提取二进制指数并从
[1,4)范围内的数字计算平方根。现在需要
frexp()从中
<math.h>获取二进制指数,但是可以通过从IEEE-754数字格式中提取比特而不使用来获得该指数
frexp()。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)