Skip to content

Commit 3d676db

Browse files
committed
arctan
1 parent 22d9145 commit 3d676db

File tree

1 file changed

+25
-13
lines changed

1 file changed

+25
-13
lines changed

src/main/java/org/devore/utils/NumberUtils.java

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,38 @@ private static BigDecimal approximatePi() {
3232

3333
/**
3434
* 使用泰勒级数展开计算arctan(x)
35-
* @param x x
36-
* @param mc 精度
35+
* @param x 输入值,|x| ≤ 1时效果最好
36+
* @param mc 精度上下文
3737
* @return arctan(x)
3838
*/
3939
public static BigDecimal arctan(BigDecimal x, MathContext mc) {
40+
if (x.compareTo(BigDecimal.ZERO) == 0)
41+
return BigDecimal.ZERO;
42+
boolean needAdjust = x.abs().compareTo(BigDecimal.ONE) > 0;
43+
BigDecimal workingX = needAdjust ? BigDecimal.ONE.divide(x, mc) : x;
4044
BigDecimal result = BigDecimal.ZERO;
41-
BigDecimal xSquared = x.multiply(x);
42-
BigDecimal term = x;
43-
boolean add = true;
45+
BigDecimal xSquared = workingX.multiply(workingX, mc);
46+
BigDecimal term = workingX;
4447
BigDecimal tolerance = BigDecimal.ONE.scaleByPowerOfTen(-mc.getPrecision());
45-
for (int i = 1; term.abs().compareTo(tolerance) > 0; i += 2) {
46-
if (add)
47-
result = result.add(term);
48-
else
49-
result = result.subtract(term);
50-
term = term.multiply(xSquared).divide(
51-
BigDecimal.valueOf(i + 2), mc);
48+
int n = 0;
49+
boolean add = true;
50+
while (term.abs().compareTo(tolerance) >= 0) {
51+
result = add? result.add(term, mc): result.subtract(term, mc);
52+
n++;
53+
term = term.multiply(xSquared, mc)
54+
.multiply(BigDecimal.valueOf(2L * n - 1), mc)
55+
.divide(BigDecimal.valueOf(2L * n + 1), mc);
5256
add = !add;
57+
if (n > mc.getPrecision() * 10)
58+
break;
5359
}
54-
return result;
60+
if (needAdjust) {
61+
BigDecimal piOver2 = BigDecimal.valueOf(Math.PI).round(mc).divide(BigDecimal.valueOf(2), mc);
62+
result = piOver2.subtract(result, mc);
63+
if (x.compareTo(BigDecimal.ZERO) < 0)
64+
result = result.negate();
65+
}
66+
return result.round(mc);
5567
}
5668

5769
/**

0 commit comments

Comments
 (0)