ph-math/src/main/java/com/helger/numbercruncher/mathutils/BigFunctions.java
public static BigDecimal exp (final BigDecimal x, final int scale)
  {
    // e^0 = 1
    if (x.signum () == 0)
    {
      return BigDecimal.ONE;
    }

    // If x is negative, return 1/(e^-x).
    if (x.signum () == -1)
    {
      return BigDecimal.ONE.divide (exp (x.negate (), scale), scale, RoundingMode.HALF_EVEN);
    }

    // Compute the whole part of x.
    BigDecimal xWhole = x.setScale (0, RoundingMode.DOWN);

    // If there isn't a whole part, compute and return e^x.
    if (xWhole.signum () == 0)
      return _expTaylor (x, scale);

    // Compute the fraction part of x.
    final BigDecimal xFraction = x.subtract (xWhole);

    // z = 1 + fraction/whole
    final BigDecimal z = BigDecimal.ONE.add (xFraction.divide (xWhole, scale, RoundingMode.HALF_EVEN));

    // t = e^z
    final BigDecimal t = _expTaylor (z, scale);

    final BigDecimal maxLong = BigDecimal.valueOf (Long.MAX_VALUE);
    BigDecimal result = BigDecimal.ONE;

    // Compute and return t^whole using intPower().
    // If whole > Long.MAX_VALUE, then first compute products
    // of e^Long.MAX_VALUE.
    while (xWhole.compareTo (maxLong) >= 0)
    {
      result = result.multiply (intPower (t, Long.MAX_VALUE, scale)).setScale (scale, RoundingMode.HALF_EVEN);
      xWhole = xWhole.subtract (maxLong);

      Thread.yield ();
    }
    return result.multiply (intPower (t, xWhole.longValue (), scale)).setScale (scale, RoundingMode.HALF_EVEN);
  }
public static BigDecimal exp (final BigDecimal x, final int scale)
  {
    // e^0 = 1
    if (x.signum () == 0)
    {
      return BigDecimal.ONE;
    }

    // If x is negative, return 1/(e^-x).
    if (x.signum () == -1)
    {
      return BigDecimal.ONE.divide (exp (x.negate (), scale), scale, RoundingMode.HALF_EVEN);
    }

    // Compute the whole part of x.
    BigDecimal xWhole = x.setScale (0, RoundingMode.DOWN);

    // If there isn't a whole part, compute and return e^x.
    if (xWhole.signum () == 0)
      return _expTaylor (x, scale);

    // Compute the fraction part of x.
    final BigDecimal xFraction = x.subtract (xWhole);

    // z = 1 + fraction/whole
    final BigDecimal z = BigDecimal.ONE.add (xFraction.divide (xWhole, scale, RoundingMode.HALF_EVEN));

    // t = e^z
    final BigDecimal t = _expTaylor (z, scale);

    final BigDecimal maxLong = BigDecimal.valueOf (Long.MAX_VALUE);
    BigDecimal result = BigDecimal.ONE;

    // Compute and return t^whole using intPower().
    // If whole > Long.MAX_VALUE, then first compute products
    // of e^Long.MAX_VALUE.
    while (xWhole.compareTo (maxLong) >= 0)
    {
      result = result.multiply (intPower (t, Long.MAX_VALUE, scale)).setScale (scale, RoundingMode.HALF_EVEN);
      xWhole = xWhole.subtract (maxLong);

      Thread.yield ();
    }
    return result.multiply (intPower (t, xWhole.longValue (), scale)).setScale (scale, RoundingMode.HALF_EVEN);
  }
Compute e^x to a given scale. Break x into its whole and fraction parts and
compute (e^(1 + fraction/whole))^whole using Taylor's formula.

@param x
the value of x
@param scale
the desired scale of the result
@return the result value