12.1 正整数平方根求法
根号2求法
我们时常在短视频里刷到根号2的连分数求法。也就是下面的迭代公式:
x=12+12+12+12+⋯2=1+x
x = \frac1{2+\frac1{2 +\frac1{2+\frac1{2 +\cdots}}}}\\
\sqrt2=1+x
x=2+2+2+2+⋯11112=1+x
我们先用代码迭代一下试试:
package cn.edu.ncepu;/*** 求根号2* 2025-11-11** @author 醒过来摸鱼*/
public class Main {public static void main(String[] args) {double x = 1;double nextX = 0;while (x != nextX) {x = nextX;nextX = 1/(2+x);}x = 1+x;System.out.println(x);System.out.println(x==Math.sqrt(2d));}
}
结果是:
1.4142135623730951
true
迭代原理
连分数迭代法的原理是什么?假设求y\sqrt{y}y,小于y\sqrt{y}y的最大整数为aaa,y\sqrt{y}y的小数部分是x=y−ax=\sqrt{y}-ax=y−a,那么就有:
y−a=x(y−a)(y+a)=y−a2(x+2a)x=y−a2x=y−a22a+x
\sqrt{y}-a=x\\
(\sqrt{y}-a)(\sqrt{y}+a)=y-a^2\\
(x+2a)x=y-a^2\\
x=\frac{y-a^2}{2a+x}\\
y−a=x(y−a)(y+a)=y−a2(x+2a)x=y−a2x=2a+xy−a2
这样小数部分的迭代公式就出来了:
x=y−a22a+y−a22a+y−a22a+y−a22a+⋯
x=\frac{y-a^2}{2a+\frac{y-a^2}{2a+\frac{y-a^2}{2a+\frac{y-a^2}{2a+\cdots}}}}\\
x=2a+2a+2a+2a+⋯y−a2y−a2y−a2y−a2
我们用这个求一下任意正整数的平方根试试:
/*** 求根号2* 2025-11-11** @author 醒过来摸鱼*/
public class Sqrt {public static void main(String[] args) {double x = sqrt(14);System.out.println(x);System.out.println(x == Math.sqrt(14));}public static double sqrt(int y) {if (y < 1) {throw new IllegalArgumentException("请输入正整数");}int a = getA(y);int numerator = y - a * a;double x = 1d;while (true) {double newX = numerator / (2 * a + x);if (Math.abs(newX - x) < 1e-15) {break;}x = newX;}return a + x;}private static int getA(int y) {int i = 0;while (i * i < y) {i++;}return i - 1;}
}
emsp;虽然算出来与API算出来的14\sqrt{14}14有误差,但是也可以接受:
3.7416573867739418
false
当然,本文的目的不是为了单纯计算正整数的平方根,而是为了引出高次方差的数值解法。
