- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在学习一门类(class),讲师使用以下代码在 Java 中实现平方根功能 -
public class Sqrt {
public static void main(String[] args) {
// read in the command-line argument
double c = Double.parseDouble(args[0]);
double epsilon = 1.0e-15; // relative error tolerance
double t = c; // estimate of the square root of c
// repeatedly apply Newton update step until desired precision is achieved
while (Math.abs(t - c/t) > epsilon*t) {
t = (c/t + t) / 2.0;
}
// print out the estimate of the square root of c
System.out.println(t);
}
}
但是,如果我将 while 循环条件稍微更改为 while (Math.abs(t - (c/t)) >= epsilon)
而不是 while (Math.abs( t - (c/t)) >= t * epsilon)
,对于某些输入(例如 234.0.0.t),程序陷入无限循环。
我使用 Eclipse 调试器,发现我的代码在某个点之后返回一个接近 234 平方根的 t 值,但仍然大于 EPSILON。并且使用更新公式,每次迭代后都会产生相同的 t 值,因此循环会永远卡在那里。
有人可以解释为什么程序在使用 >= EPSILON
时失败,但在使用 >= t * EPSILON
时工作得很好吗?根据我的理解,考虑到 EPSILON 的值极小,t * EPSILON 最终应该不会与 EPSILON 相差太大,但在程序中实现时差别却很大。
最佳答案
您实际上可以使用调试器来查看数字的进展情况,以及为什么当 epsilon
未乘以 t
时,234 的平方根会导致无休止的循环。
我使用带有日志记录断点的 IntelliJ 来查看数字的进展情况以及为什么会发生无休止的循环:
首先,我在日志断点中使用了这个表达式:
" " + Math.abs(t - c/t) + " " + epsilon
对于此代码:
private static void calcRoot(String arg) {
// read in the command-line argument
double c = Double.parseDouble(arg);
double epsilon = 1.0e-15; // relative error tolerance
double t = c; // estimate of the square root of c
// repeatedly apply Newton update step until desired precision is achieved
while (Math.abs(t - c/t) > epsilon ) {
t = (c/t + t) / 2.0;
}
// print out the estimate of the square root of c
System.out.println(t);
}
这是证明 epsilon 实际上小于 Math.abs(t - c/t)
的结果,而这个 Math.abs(t - c/t)
停止前进:
233.0 1.0E-15
115.50851063829788 1.0E-15
55.82914775415816 1.0E-15
24.47988606961853 1.0E-15
7.647106514310517 1.0E-15
0.927185521197492 1.0E-15
0.014043197832668497 1.0E-15
3.2230278765865705E-6 1.0E-15
1.723066134218243E-13 1.0E-15
1.7763568394002505E-15 1.0E-15
1.7763568394002505E-15 1.0E-15
1.7763568394002505E-15 1.0E-15
1.7763568394002505E-15 1.0E-15
1.7763568394002505E-15 1.0E-15
1.7763568394002505E-15 1.0E-15
1.7763568394002505E-15 1.0E-15
...
如果我随后使用 epsilon * t
I 并将日志表达式更新为 ""+ Math.abs(t - c/t) + ""+ epsilon * t
我可以看到完全不同的控制台输出:
233.0 2.34E-13
115.50851063829788 1.175E-13
55.82914775415816 5.974574468085106E-14
24.47988606961853 3.1831170803771985E-14
7.647106514310517 1.959122776896272E-14
0.927185521197492 1.5767674511807463E-14
0.014043197832668497 1.5304081751208715E-14
3.2230278765865705E-6 1.529706015229238E-14
1.723066134218243E-13 1.5297058540778443E-14
更新
如果您对 BigDecimal
类尝试相同的操作,您将能够计算 234
的平方根,以防您选择足够的舍入数字(请参阅比例
变量如下):
private static void calcRootBig(String arg) {
// read in the command-line argument
BigDecimal c = new BigDecimal(arg);
BigDecimal epsilon = new BigDecimal(1.0e-15); // relative error tolerance
BigDecimal t = new BigDecimal(c.toString()); // estimate of the square root of c
BigDecimal two = new BigDecimal("2.0");
// repeatedly apply Newton update step until desired precision is achieved
int scale = 10;
while (t.subtract(c.divide(t, scale, RoundingMode.CEILING)).abs().compareTo(epsilon) > 0) {
t = c.divide(t, scale, RoundingMode.CEILING).add(t).divide(two, scale, RoundingMode.CEILING);
}
// print out the estimate of the square root of c
System.out.println(t);
}
但是,如果您只选择 3 作为舍入比例,您将再次陷入无休止的循环。
所以看来是浮点除法的精度实际上导致了您的情况的无限循环。 epsilon * t
的乘法只是克服默认浮点运算中舍入精度不足的一个技巧。
关于java - 使用 Newton-Raphson 方法计算平方根的 While 循环条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55954989/
我是这个主题的新手,找不到原因:程序有时有效,有时无效(问完问题后,它根本不想接受我的答案,而我可以我想写多少就写多少,它没有反应,只是列出数字,我给了小费) #include float ab
我警告你,这可能会造成混淆,而且我编写的代码与其说是完成的代码,不如说是思维导图。 我正在尝试实现 Newton-Raphson 方法来求解方程。我想不通的是如何写这个 Python 中的方程,用于根
在下面的代码中,当我选择例如“max_n_iterations”等于 1 时,列表“approximations”在打印时显示两个元素,而它应该只显示一个元素(初始 x)。 这是什么原因? #This
我正在尝试使用 Newton Raphson 方法找到 N 个根。这是我对相同的实现... double derive(int guess, int m, int n) { return gues
我有一个大问题。我需要用 C++ 函数或类求解 3 个变量的 3 个方程的非线性系统。我考虑过使用 Newton-Raphson 方法来执行解决方案。不幸的是,我没有找到可以为我做到这一点的源代码。会
问题的简要说明:我使用 Newton Raphson 算法在多项式中求根,但在某些情况下不起作用。为什么? 我从“c++ 中的数值食谱”中获取了一种 Newton Raphson 混合算法,该算法会在
我编写了牛顿拉夫森求根算法的简单实现,它采用初始猜测 init、一元函数 f 和公差 tol 作为参数,如下所示: bool newton_raphson(double& init,
我正在尝试在 R 中使用 Newton-Raphson 算法来最小化我为一个非常具体的问题编写的对数似然函数。老实说,估计方法超出了我的能力范围,但我知道我的领域(心理测量学)中有很多人使用 NR 算
public class Sqrt { public static void main(String[] args) { double EPS = 1
我在一个简单的程序中工作,该程序使用 Newton-Raphson 方法计算任何给定函数的根。在这个程序中,我必须打印找到的根和进行的迭代次数。程序本身很好,我可以找到任何给定函数的根,但我无法正确计
x=float(raw_input('Enter a number to show its square root')) precise = 0.01 g=x/2.0 while abs(g**2-x
我在 Newton-Raphson 迭代的脚本中收到 'float' object is not Iterable 错误。我将迭代应用于函数 f(x) = sin(x),并将 x0 = 3 应用于迭代
#include #include #include float f(float x); float df(float x); void main() { float x0, x1, m
我目前正在学习一门类(class),讲师使用以下代码在 Java 中实现平方根功能 - public class Sqrt { public static void main(String[]
我已经编写了以下代码来使用牛顿法计算平方根,但每次运行它都会溢出。我试过自己检查,但没有发现任何错误。你们能帮帮我吗? double root(double n,double init){ i
我正在编写一个程序,用一个方程在 Java 中应用 Newton-Raphson 方法: f(x) = 3x - e^x + sin(x) 和 g(x) = f'(x) = 3- e^x + cos
我是 matlab 的新手,我需要创建一个函数,以起始近似值 x = a 执行 Newton-Raphson 方法的 n 次迭代。此起始近似值不算作交互,另一个要求是需要 for 循环。我查看了发布的
Newton-Raphson 平方法的时间复杂度是多少? Wikipedia: Newton's method 最佳答案 来自 http://en.citizendium.org/wiki/Newto
对于这个问题,我们需要利用 Newton-Raphson 方法来定位特定函数的根。 该代码适用于输入为单个值的情况,但当输入为向量时,答案不太正确。 例如,当 x=2是一个输入,值 2.5933返回时
我目前正在遍历一组非常大的数据~85GB(~600M 行)并简单地使用 newton-raphson 来计算一个新参数。截至目前,我的代码非常慢,关于如何加快速度的任何提示? BSCallClass
我是一名优秀的程序员,十分优秀!