我在java中实现了Babylonian/Heron的方法来获得一个数字的平方根,基于维基百科信息
目前我有:
public static void main(String[] args) {
System.out.println(Sqrt.sqrt1(8));
//System.out.println(Sqrt.sqrt2(8)); //Infinite loop
System.out.println(Sqrt.sqrt3(8));
System.out.println(Sqrt.sqrt4(8));
}
static float sqrt1(float x) {
float b = 0, h = x;
while (b != h) {
b = (h + b) / 2;
h = x / b;
}
return b;
}
static double sqrt2(double x) {
double b = x, h = 0;
while (b != h) {
b = (h + b) / 2;
h = x / b;
}
return b;
}
static double sqrt3(double x) {
double b = x, h = 0;
while (Math.abs(b - h) > 0.000000000001) {
b = (h + b) / 2;
h = x / b;
}
return b;
}
static double sqrt4(double x) {
double r = x, t = 0;
while (t != r) {
t = r;
r = (x / r + r) / 2;
}
return r;
}
输出将是:
2.828427
2.82842712474619
2.82842712474619
sqrt2 方法将永远循环,但这只会发生在双精度数上,因为 sqrt1 方法适用于浮点数。我不知道这是为什么。因此,如果我想使用双打,sqrt3 方法看起来像是要走的路。
我对我实施哪些方法有点困惑,¿巴比伦方法与苍鹭方法相同吗?
据我了解,巴比伦方法基于这样一个事实,即正方形的边是正方形(x)面积的平方根。所以你可以从一个尺寸为 bh 的矩形开始,得到两边的平均值 (b=b+h/2),然后将此结果视为较小矩形的边,当然得到另一边 (h=x /b)。矩形将开始接近所需的正方形。这是我在 sqrt1、sqrt2 和 sqrt3 方法中所做的:
while (b != h) {
b = (h + b) / 2;
h = x / b;
}
另一方面,维基百科链接说巴比伦/苍鹭方法是相同的,并将其描述为:
“基本思想是,如果 x 高估了非负实数 S 的平方根,那么 S/x 将被低估,因此可以合理地预期这两个数字的平均值可以提供更好的近似值”
你可以在 sqrt4 方法中看到这个实现:
while (t != r) {
t = r;
r = (x/r + r) / 2;
}
据我所知,这两种方法不一样,但相似。如果我错了,请纠正我。
有趣的是我做不到:while (b != h) {
当 b 和 h 是 sqrt2 方法中所示的双精度数时,因为它将永远循环。相反,我使用while (Math.abs(b - h) > 0.000000000001) {
但是,我可以做到:while (t != r) {
使用 b 和 h 加倍,如 sqrt4 所示。
我会很感激有人解释这种行为。
- - - - - -编辑: - - - - - - - - - - - - - - - - - - - ----------------------
正如所建议的,两种算法都是相同的,但实现方式不同。但是,以下建议的代码永远循环,就像 x=8 的 sqrt2 一样:
static double sqrt5(double x) {
double b = x;
while (b != x/b) {
b = (x / b + b) / 2;
}
return b;
}
那么.. sqrt4 与其他实现有什么区别?为什么它不像其他人那样永远循环?