Last active
October 27, 2022 09:29
-
-
Save fftlxyz/f7619d0717428b346591443f2bc6c032 to your computer and use it in GitHub Desktop.
泰勒展开&牛顿迭代的例子
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* 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