Skip to content

Instantly share code, notes, and snippets.

@fftlxyz
Last active October 27, 2022 09:29
Show Gist options
  • Save fftlxyz/f7619d0717428b346591443f2bc6c032 to your computer and use it in GitHub Desktop.
Save fftlxyz/f7619d0717428b346591443f2bc6c032 to your computer and use it in GitHub Desktop.
泰勒展开&牛顿迭代的例子
/**
*
* 1. 通过泰勒展开的方式求e、sin95
* 2. 牛顿迭代法求平方根 (https://netedu.xauat.edu.cn/jpkc/netedu/jpkc2009/jsff/content/dzja/3.4.htm)
*/
public class KataMathTaylorFormula {
public static void main(String[] args) {
System.out.println(exp(1.5));
System.out.println(Math.exp(1.5));
System.out.println(sin95());
System.out.println(Math.sin(Math.PI * 95.0 / 180));
// sqrt:2.0, loopCount:5
// sqrt:21.0, loopCount:7
// sqrt:211.0, loopCount:9
// sqrt:2111.0, loopCount:11
// sqrt:21111.0, loopCount:12
// sqrt:121111.0, loopCount:14
// sqrt:2.121110001E9, loopCount:21
// 收敛的速度还是蛮快的
checkSqrt(2);
checkSqrt(21);
checkSqrt(211);
checkSqrt(2111);
checkSqrt(21111);
checkSqrt(121111);
checkSqrt(2121110001);
}
public static void checkSqrt(double n) {
double mySqrt = sqrt(n);
double mathSqrt = Math.sqrt(n);
if (Math.abs(mathSqrt - mySqrt) > 0.0001) {
System.out.println(mySqrt + ", mathSqrt:" + mathSqrt + ", diff:" + (mathSqrt - mySqrt));
}
}
// e^x 在0展开,求e
public static double exp(double x) {
double exp = 1;
long factorial = 1;
double xn = 1;
for (int i = 1; i < 10; ++i) {
factorial *= i;
xn *= x;
exp += xn / factorial;
}
return exp;
}
// sinx 在 pi/2 展开,就sin(95度)
public static double sin95() {
double delta = Math.PI * 5.0 / 180;
double result = 1;
long factorial = 1;
double deltaN = 1;
double dsin90N = -1;
for (int i = 1; i < 10; i++) {
factorial *= i;
deltaN *= delta;
if (i % 2 == 0) {
result += dsin90N * deltaN / factorial;
dsin90N = -1 * dsin90N;
}
}
return result;
}
// 通过牛顿迭代法求开平方根
public static double sqrt(double n) {
// f(x) = x^2-n
// 做泰勒在x0展开,只考虑前前两项
// f(x) = x0^2 -n + 2*x0 (x-x0)
// f(x) = 0,得x = x0 - (x0*x0 -n) / (2*x0)
// 迭代即可
int loopCount = 1;
double xn = n;
while (Math.abs(xn * xn - n) > 0.000001 && loopCount++ < 100) {
xn = xn - (xn * xn - n) / (2 * xn);
}
if (loopCount == 100) {
throw new RuntimeException("不收敛:" + loopCount);
}
System.out.println("sqrt:" + n + ", loopCount:" + loopCount);
return xn;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment