use of java.math.MathContext in project big-math by eobermuhlner.
the class BigDecimalMath method log2.
/**
* Calculates the logarithm of {@link BigDecimal} x to the base 2.
*
* @param x the {@link BigDecimal} to calculate the logarithm base 2 for
* @param mathContext the {@link MathContext} used for the result
* @return the calculated natural logarithm {@link BigDecimal} to the base 2 with the precision specified in the <code>mathContext</code>
* @throws ArithmeticException if x <= 0
*/
public static BigDecimal log2(BigDecimal x, MathContext mathContext) {
MathContext mc = new MathContext(mathContext.getPrecision() + 4, mathContext.getRoundingMode());
BigDecimal result = log(x, mc).divide(logTwo(mc), mc);
return result.round(mathContext);
}
use of java.math.MathContext in project big-math by eobermuhlner.
the class BigDecimalMath method powInteger.
/**
* Calculates {@link BigDecimal} x to the power of the integer value y (x<sup>y</sup>).
*
* <p>The value y MUST be an integer value.</p>
*
* @param x the {@link BigDecimal} value to take to the power
* @param integerY the {@link BigDecimal} <strong>integer</strong> value to serve as exponent
* @param mathContext the {@link MathContext} used for the result
* @return the calculated x to the power of y with the precision specified in the <code>mathContext</code>
* @see #pow(BigDecimal, long, MathContext)
*/
private static BigDecimal powInteger(BigDecimal x, BigDecimal integerY, MathContext mathContext) {
if (fractionalPart(integerY).signum() != 0) {
throw new IllegalArgumentException("Not integer value: " + integerY);
}
if (integerY.signum() < 0) {
return ONE.divide(powInteger(x, integerY.negate(), mathContext), mathContext);
}
MathContext mc = new MathContext(Math.max(mathContext.getPrecision(), -integerY.scale()) + 30, mathContext.getRoundingMode());
BigDecimal result = ONE;
while (integerY.signum() > 0) {
BigDecimal halfY = integerY.divide(TWO, mc);
if (fractionalPart(halfY).signum() != 0) {
// odd exponent -> multiply result with x
result = result.multiply(x, mc);
integerY = integerY.subtract(ONE);
halfY = integerY.divide(TWO, mc);
}
if (halfY.signum() > 0) {
// even exponent -> square x
x = x.multiply(x, mc);
}
integerY = halfY;
}
return result.round(mathContext);
}
use of java.math.MathContext in project big-math by eobermuhlner.
the class BigDecimalMath method acos.
/**
* Calculates the arc cosine (inverted cosine) of {@link BigDecimal} x.
*
* <p>See: <a href="http://en.wikipedia.org/wiki/Arccosine">Wikipedia: Arccosine</a></p>
*
* @param x the {@link BigDecimal} to calculate the arc cosine for
* @param mathContext the {@link MathContext} used for the result
* @return the calculated arc sine {@link BigDecimal} with the precision specified in the <code>mathContext</code>
* @throws ArithmeticException if x > 1 or x < -1
*/
public static BigDecimal acos(BigDecimal x, MathContext mathContext) {
if (x.compareTo(ONE) > 0) {
throw new ArithmeticException("Illegal acos(x) for x > 1: x = " + x);
}
if (x.compareTo(MINUS_ONE) < 0) {
throw new ArithmeticException("Illegal acos(x) for x < -1: x = " + x);
}
MathContext mc = new MathContext(mathContext.getPrecision() + 6, mathContext.getRoundingMode());
BigDecimal result = pi(mc).divide(TWO, mc).subtract(asin(x, mc), mc);
return result.round(mathContext);
}
use of java.math.MathContext in project big-math by eobermuhlner.
the class BigDecimalMath method pow.
/**
* Calculates {@link BigDecimal} x to the power of <code>long</code> y (x<sup>y</sup>).
*
* <p>The implementation tries to minimize the number of multiplications of {@link BigDecimal x} (using squares whenever possible).</p>
*
* <p>See: <a href="https://en.wikipedia.org/wiki/Exponentiation#Efficient_computation_with_integer_exponents">Wikipedia: Exponentiation - efficient computation</a></p>
*
* @param x the {@link BigDecimal} value to take to the power
* @param y the <code>long</code> value to serve as exponent
* @param mathContext the {@link MathContext} used for the result
* @return the calculated x to the power of y with the precision specified in the <code>mathContext</code>
*/
public static BigDecimal pow(BigDecimal x, long y, MathContext mathContext) {
MathContext mc = new MathContext(mathContext.getPrecision() + 10, mathContext.getRoundingMode());
if (y < 0) {
return ONE.divide(pow(x, -y, mc), mc).round(mathContext);
}
BigDecimal result = ONE;
while (y > 0) {
if ((y & 1) == 1) {
// odd exponent -> multiply result with x
result = result.multiply(x, mc);
y -= 1;
}
if (y > 0) {
// even exponent -> square x
x = x.multiply(x, mc);
}
y >>= 1;
}
return result.round(mathContext);
}
use of java.math.MathContext in project big-math by eobermuhlner.
the class BigDecimalMath method sqrt.
/**
* Calculates the square root of {@link BigDecimal} x.
*
* <p>See <a href="http://en.wikipedia.org/wiki/Square_root">Wikipedia: Square root</a></p>
*
* @param x the {@link BigDecimal} value to calculate the square root
* @param mathContext the {@link MathContext} used for the result
* @return the calculated square root of x with the precision specified in the <code>mathContext</code>
* @throws ArithmeticException if x < 0
*/
public static BigDecimal sqrt(BigDecimal x, MathContext mathContext) {
switch(x.signum()) {
case 0:
return ZERO;
case -1:
throw new ArithmeticException("Illegal sqrt(x) for x < 0: x = " + x);
}
int maxPrecision = mathContext.getPrecision() + 6;
BigDecimal acceptableError = ONE.movePointLeft(mathContext.getPrecision() + 1);
BigDecimal result;
if (isDoubleValue(x)) {
result = BigDecimal.valueOf(Math.sqrt(x.doubleValue()));
} else {
result = x.divide(TWO, mathContext);
}
if (result.multiply(result, mathContext).compareTo(x) == 0) {
// early exit if x is a square number
return result.round(mathContext);
}
int adaptivePrecision = EXPECTED_INITIAL_PRECISION;
BigDecimal last;
do {
last = result;
adaptivePrecision = adaptivePrecision * 2;
if (adaptivePrecision > maxPrecision) {
adaptivePrecision = maxPrecision;
}
MathContext mc = new MathContext(adaptivePrecision, mathContext.getRoundingMode());
result = x.divide(result, mc).add(last, mc).divide(TWO, mc);
} while (adaptivePrecision < maxPrecision || result.subtract(last).abs().compareTo(acceptableError) > 0);
return result.round(mathContext);
}
Aggregations