求根号2, 网易的一道面试题
# 二分法 def solve(): l, r = 1, 2 eps = 1e-7 while l + eps < r: mid = (l + r) / 2 if mid * mid < 2: l = mid else: r = mid return l # print('{:.6f}'.format(solve())) # 泰勒展开 # f(x) = x^{1 / 2} # f(x) = f(1) + f'(1)(x-1)+f''(1)/ 2 (x-1)**2+f'''(1)/ 3! (x-1)**3+.... # = 1 + f'(1) + f''(1) / 2 + f'''(1)/ 3! + ... # = 1 + 0.5 + 0.5*(0.5 - 1) / 2 + 0.5*(0.5 - 1) * (0.5 - 2) / 3! + ... def solve2(): def daoshu(x0, n): # a, b = 1, 0.5 res_a, res_b = 1, 0.5 res_a_div_jiechen = 1 dx = 1 for i in range(n): res_a_div_jiechen = res_a_div_jiechen * res_b / (i + 1) # 0.5*(0.5 - 1) * (0.5 - 2) * ...*(0.5 - n + 1) / n! res_a *= res_b res_b = res_b - 1 dx *= (2 - x0) return res_a_div_jiechen * x0 ** res_b * dx # x=2, x0=dx =x-x0 = 1 res = 0 x0 = 1 #1.5 cnt = 0 eps = 1e-6 while True: now = daoshu(x0, cnt) # print(now) if abs(now) < eps: break res += now cnt += 1 return res # print('{:.6f}'.format(solve2())) # 牛顿法 # f(x) = x**2 - 2 # x_next = x - f(x) / f'(x) def solve3(): x0 = 2 eps = 1e-7 while True: x0 = x0 - (x0 * x0 - 2) / (2 * x0) if abs(x0 * x0 - 2) < eps: break return x0 # print('{:.6f}'.format(solve3())) # 梯度下降法 # 定义loss: (x*x - 2) * 2 def sgd(): def grad(x): return 2 * (x*x -2) * 2 * x x0 = 2 eps = 1e-7 lr = 0.001 while True: x0_grad = grad(x0) x0 = x0 - lr * x0_grad if abs(x0 * x0 - 2) < eps: break return x0 # print('{:.6f}'.format(sgd())) # 连分数逼近法 # 根号2 = 1 + 1 / (2 + 1 / (2 + 1 / (2 + ...))) def lianfengshu(): # 根号2 = 1 + 1 / (2 + ...) now = 1 eps = 1e-7 while True: now = 1 / (2 + now) if abs((1 + now) ** 2 - 2) < eps: break return 1 + now # print('{:.6f}'.format(lianfengshu()))