eobermuhlner/big-math

might has issue with MathContext.UNLIMITED

Closed this issue · 2 comments

here is MathContext.UNLIMITED
public static final MathContext UNLIMITED = new MathContext(0, RoundingMode.HALF_UP);
precision is zero then
public static BigDecimal pow(BigDecimal x, long y, MathContext mathContext) { MathContext mc = new MathContext(mathContext.getPrecision() + 10, mathContext.getRoundingMode());
it changed form Unlimited to 10 digits precision
maybe change it to
MathContext mc = new MathContext(mathContext.getPrecision()==0?65535/*<<some big number?*/:mathContext.getPrecision(), mathContext.getRoundingMode());
maybe
if(mathContext.getPrecision()==0) throw new UnsupportedOperationException("Unlimited MathContext is not supported");

Bug confirmed.

I will probably go for the

if(mathContext.getPrecision()==0) throw new UnsupportedOperationException("Unlimited MathContext is not supported");

solution

Fix BigDecimalMath functions with MathContext.UNLIMITED

The behaviour of the BigDecimalMath functions when being used with the MathContext.UNLIMITED was badly defined.
In many cases the calculation was done with a low precision like 10.

The functions that calculate the result with an algorithm using well defined and obvious operations
may throw the same ArithmeticException as the underlying BigDecimal operations
if the specified MathContext has a precision of 0 (for example MathContext.UNLIMITED):

  • BigDecimalMath.reciprocal(BigDecimal)
  • BigDecimalMath.bernoulli(int, MathContext)
  • BigDecimalMath.factorial(BigDecimal, MathContext) with integer argument
  • BigDecimalMath.gamma(BigDecimal, MathContext) with integer argument
  • BigDecimalMath.pow(BigDecimal, long, MathContext)

All other functions that use approximations to calculate the result will throw a UnsupportedOperationException
if the specified MathContext has a precision of 0 (for example MathContext.UNLIMITED):

  • BigDecimalMath.factorial(BigDecimal, MathContext) with non-integer argument
  • BigDecimalMath.gamma(BigDecimal, MathContext) with non-integer argument
  • BigDecimalMath.pow(BigDecimal, BigDecimal, MathContext)
  • BigDecimalMath.sqrt(BigDecimal, MathContext)
  • BigDecimalMath.root(BigDecimal, BigDecimal, MathContext)
  • BigDecimalMath.log(BigDecimal, MathContext)
  • BigDecimalMath.log2(BigDecimal, MathContext)
  • BigDecimalMath.log10(BigDecimal, MathContext)
  • BigDecimalMath.pi(MathContext)
  • BigDecimalMath.e(MathContext)
  • BigDecimalMath.exp(BigDecimal, MathContext)
  • BigDecimalMath.sin(BigDecimal, MathContext)
  • BigDecimalMath.asin(BigDecimal, MathContext)
  • BigDecimalMath.cos(BigDecimal, MathContext)
  • BigDecimalMath.acos(BigDecimal, MathContext)
  • BigDecimalMath.tan(BigDecimal, MathContext)
  • BigDecimalMath.atan(BigDecimal, MathContext)
  • BigDecimalMath.atan2(BigDecimal, BigDecimal MathContext)
  • BigDecimalMath.cot(BigDecimal, MathContext)
  • BigDecimalMath.acot(BigDecimal, MathContext)
  • BigDecimalMath.sinh(BigDecimal, MathContext)
  • BigDecimalMath.cosh(BigDecimal, MathContext)
  • BigDecimalMath.tanh(BigDecimal, MathContext)
  • BigDecimalMath.coth(BigDecimal, MathContext)
  • BigDecimalMath.asinh(BigDecimal, MathContext)
  • BigDecimalMath.acosh(BigDecimal, MathContext)
  • BigDecimalMath.atanh(BigDecimal, MathContext)
  • BigDecimalMath.acoth(BigDecimal, MathContext)