BigComplexMath { public static BigComplex factorial(BigComplex x, MathContext mathContext) { if (x.isReal() && BigDecimalMath.isIntValue(x.re)) { return BigComplex.valueOf(BigDecimalMath.factorial(x.re.intValueExact()).round(mathContext)); } MathContext mc = new MathContext(mathContext.getPrecision() * 2, mathContext.getRoundingMode()); int a = mathContext.getPrecision() * 13 / 10; List<BigDecimal> constants = BigDecimalMath.getSpougeFactorialConstants(a); BigDecimal bigA = BigDecimal.valueOf(a); boolean negative = false; BigComplex factor = BigComplex.valueOf(constants.get(0)); for (int k = 1; k < a; k++) { BigDecimal bigK = BigDecimal.valueOf(k); factor = factor.add(BigComplex.valueOf(constants.get(k)).divide(x.add(bigK), mc), mc); negative = !negative; } BigComplex result = pow(x.add(bigA, mc), x.add(BigDecimal.valueOf(0.5), mc), mc); result = result.multiply(exp(x.negate().subtract(bigA, mc), mc), mc); result = result.multiply(factor, mc); return result.round(mathContext); }  static BigComplex reciprocal(BigComplex x, MathContext mathContext); static BigComplex conjugate(BigComplex x); static BigDecimal abs(BigComplex x, MathContext mathContext); static BigDecimal absSquare(BigComplex x, MathContext mathContext); static BigDecimal angle(BigComplex x, MathContext mathContext); static BigComplex factorial(BigComplex x, MathContext mathContext); static BigComplex gamma(BigComplex x, MathContext mathContext); static BigComplex exp(BigComplex x, MathContext mathContext); static BigComplex sin(BigComplex x, MathContext mathContext); static BigComplex cos(BigComplex x, MathContext mathContext); static BigComplex tan(BigComplex x, MathContext mathContext); static BigComplex atan(BigComplex x, MathContext mathContext); static BigComplex acot(BigComplex x, MathContext mathContext); static BigComplex asin(BigComplex x, MathContext mathContext); static BigComplex acos(BigComplex x, MathContext mathContext); static BigComplex sqrt(BigComplex x, MathContext mathContext); static BigComplex log(BigComplex x, MathContext mathContext); static BigComplex pow(BigComplex x, long y, MathContext mathContext); static BigComplex pow(BigComplex x, BigDecimal y, MathContext mathContext); static BigComplex pow(BigComplex x, BigComplex y, MathContext mathContext); static BigComplex root(BigComplex x, BigDecimal n, MathContext mathContext); static BigComplex root(BigComplex x, BigComplex n, MathContext mathContext);  }
@Test public void testFactorial() { assertEquals(BigComplex.valueOf(1), BigComplexMath.factorial(BigComplex.valueOf(0), MC)); assertEquals(BigComplex.valueOf(120), BigComplexMath.factorial(BigComplex.valueOf(5), MC)); }
@Test public void testFactorialHighPrecision() { assertPrecisionCalculation( BigComplex.valueOf( new BigDecimal("-0.0459981123305585249681603480968269660113873556089014470248069472979754564331678182847798134586963875663871893"), new BigDecimal("0.312560954529664888473258907702587964452355919300835979305316051616804053286423048624964580542939407812546590")), (mc) -> BigComplexMath.factorial(BigComplex.valueOf(1.2, 2.3), mc), 5); }