In my little project, I need to do something like Math.pow(7777.66, 5555.44)
only with VERY big numbers. I came across a few solutions:
double
- but the numbers are too bigBigDecimal.pow
but no support for fractionalX^(A+B)=X^A*X^B
formula (B
is the remainder of the second num), but again no support for big X
or big A
because I still convert to double(A+B)^(C+D)
).Does anyone know of a library or an easy solution? I figured that many people deal with the same problem...
p.s. I found some library called ApFloat that claims to do it approximately, but the results I got were so approximate that even 8^2
gave me 60
...
The java. math. BigDecimal. sqrt(MathContext mc) is an inbuilt function added in Java SE 9 & JDK 9 which returns BigDecimal value of square root of a BigDecimal on which sqrt() method is applied with rounding according to the context settings.
A BigDecimal consists of an arbitrary precision integer unscaled value and a 32-bit integer scale. If zero or positive, the scale is the number of digits to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale.
Description. The java. math. BigDecimal. setScale(int newScale, RoundingMode roundingMode) returns a BigDecimal whose scale is the specified value, and whose unscaled value is determined by multiplying or dividing this BigDecimal's unscaled value by the appropriate power of ten to maintain its overall value.
Use the multiply() method to multiply one BigDecimal to another in Java. This method returns a BigDecimal whose value is (this × multiplicand), and whose scale is (this. scale() + multiplicand.
The solution for arguments under 1.7976931348623157E308 (Double.MAX_VALUE) but supporting results with MILLIONS of digits:
Since double supports numbers up to MAX_VALUE (for example, 100! in double looks like this: 9.332621544394415E157), there is no problem to use BigDecimal.doubleValue(). But you shouldn't just do Math.pow(double, double) because if the result is bigger than MAX_VALUE you will just get infinity. SO: use the formula X^(A+B)=X^A*X^B to separate the calculation to TWO powers, the big, using BigDecimal.pow, and the small (remainder of the 2nd argument), using Math.pow, then multiply. X will be copied to DOUBLE - make sure it's not bigger than MAX_VALUE, A will be INT (maximum 2147483647 but the BigDecimal.pow doesn't support integers more than a billion anyway), and B will be double, always less than 1. This way you can do the following (ignore my private constants etc):
int signOf2 = n2.signum(); try { // Perform X^(A+B)=X^A*X^B (B = remainder) double dn1 = n1.doubleValue(); // Compare the same row of digits according to context if (!CalculatorUtils.isEqual(n1, dn1)) throw new Exception(); // Cannot convert n1 to double n2 = n2.multiply(new BigDecimal(signOf2)); // n2 is now positive BigDecimal remainderOf2 = n2.remainder(BigDecimal.ONE); BigDecimal n2IntPart = n2.subtract(remainderOf2); // Calculate big part of the power using context - // bigger range and performance but lower accuracy BigDecimal intPow = n1.pow(n2IntPart.intValueExact(), CalculatorConstants.DEFAULT_CONTEXT); BigDecimal doublePow = new BigDecimal(Math.pow(dn1, remainderOf2.doubleValue())); result = intPow.multiply(doublePow); } catch (Exception e) { if (e instanceof CalculatorException) throw (CalculatorException) e; throw new CalculatorException( CalculatorConstants.Errors.UNSUPPORTED_NUMBER_ + "power!"); } // Fix negative power if (signOf2 == -1) result = BigDecimal.ONE.divide(result, CalculatorConstants.BIG_SCALE, RoundingMode.HALF_UP);
Results examples:
50!^10! = 12.50911317862076252364259*10^233996181 50!^0.06 = 7395.788659356498101260513
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With