计算根号二sqrt(2)
计算sqrt(2),要求精确到小数点后10位。常见的有二分法,牛顿迭代法,还有利用连分数的一些迭代法。
#include<iostream>
#include<vector>
#include<unordered_map>
#include <iomanip>
using namespace std;
const double eps = 1e-10;
// 二分法
double sqrt1(int x) {
x = static_cast<double>(x);
if(x == 0) return 0;
double l = 1, r = x;
while(r-l > eps) {
// cout << l << " " << r << endl;
double mid = (l + r) / 2;
if(mid * mid <= x) l = mid;
else r = mid;
}
return l;
}
// 牛顿迭代法 x_n+1 = x_n - f(x_n)/f'(x_n)
double sqrt2(int x) {
x = static_cast<double>(x);
double a = x, b = 0;
while(abs(a - b) > eps) {
b = a;
a = (a + x / a) / 2;
}
return a;
}
// 连分数法
double sqrt3(int x) {
x = static_cast<double>(x);
double a = x, b = 0;
while(abs(a - b) > eps) {
b = a;
a = (a + x / a) / 2;
}
return a;
}
// 连分数法2 \sqrt{x} = a + b/(2a + b/(2a+...))
double sqrt4(int x) {
x = static_cast<double>(x);
double a, b;
for(int i = x;x > 0;i--) { // 找到尽可能大的a
if(i * i <= x) {
a = i;
break;
}
}
b = x - a * a;
// cout << a << " " << b << endl;
double pre = 0, cur = b/(2*a);
while(abs(pre - cur) > eps) {
pre = cur;
cur = b/(2*a + cur);
}
return a + cur;
}
// 手算开平方
double sqrt5(int x) {
// 不会实现
return 0;
}
int main() {
cout << setprecision(10) << sqrt1(2) << endl;
cout << setprecision(10) << sqrt2(2) << endl;
cout << setprecision(10) << sqrt3(2) << endl;
cout << setprecision(10) << sqrt4(2) << endl;
return 0;
}
参考链接:李永乐老师_手算开平方
个性签名:时间会解决一切