Power of BigInteger for BigDecimal in Java Baeldung

I tried to get a value double

where the exponent is very large (Java BigInteger

can contain it (exponent), for example: 10 ^ 30)

That is, I want to find something like 1.75 ^ (10 ^ 30) or 1.23 ^ (34234534534222). If the output is too large, change it to get the modulus by prime like 10 ^ 9 + 7.

If I want to find the degree Integer

, I can use a method that takes arguments : BigInteger.modPow()

BigInteger

( BigInteger modPow(BigInteger exponent, BigInteger m) )

      

As far as I can do this, this is what I got in Java

new BigDecimal("1.5").pow(1000); // .pow() can get only integers as a parameter , but i want to pass a big number like a BigInteger 

      

I cannot find an equivalent for this ( BigInteger.modPow () ) in java for , or am I missing it. BigDecimal

Is there a way to do this - Compute the large cardinality of a floating point number (a Decimal

)?

Example input and output:

Input: num // or 1.5 or any decimal number. can also be an integer.

exponent: exp // large integer or long value

output: num ^ exp // num to the power exp

For example, calculating 1.23 ^ (34234534534222)

if the output is too big, change it to get the modulus to simple, like 10 ^ 9 + 7

+3


source to share


2 answers


There is a Math.BigDecimal implementation of basic math functions that has:

static java.math.BigDecimal powRound(java.math.BigDecimal x, java.math.BigInteger n) 
          Raise to an integer power and round.

      

which seems to be exactly what you need. The fact that there is an external library for it means that there is java.Math

no main implementation of a method like this.



As a side note, I can say that if your input is significantly small in terms of decimal places (so no irrational), like 1.5, you can convert it to 15/10 and do

(15^BigInteger)/(10^BigInteger)

      

with modPow(BigInteger exponent, BigInteger m)

of BigInteger

. This obviously increases the complexity and numbers to calculate.

+1


source


There are a few caveats. As Gabor Bakos pointed out, the resulting value is likely to contain too many digits, even if presented as BigDecimal

.

Also, this number of digits is growing rapidly, so computing something like 2.0 34234534534222 is completely out of scope in terms of storage (and, I suppose, in terms of time required).

You mentioned that a value can be calculated modulo a large prime number when it gets "too large". While you didn't say what exactly that means, it won't necessarily help you here, because using modulo won't truncate decimals. You will somehow have to limit the accuracy of the calculations.



However, the simplest implementation using exponentiation of squaring might look something like this:

import java.math.BigDecimal;
import java.math.BigInteger;

public class BigDecimalPow {
    public static void main(String[] args) {
        BigDecimal b = new BigDecimal(1.5);
        BigInteger e = new BigInteger("325322");
        BigDecimal result = pow(b, e);
        System.out.println("Done "+result.scale());
        System.out.println(result);
    }


    /**
     * Computes d to the power of e
     * @param b The value
     * @param e The exponent
     * @return The power
     */
    private static BigDecimal pow(BigDecimal b, BigInteger e) {
        BigDecimal result = BigDecimal.ONE;
        BigDecimal p = b;
        int skipped = 0;
        while (e.compareTo(BigInteger.ZERO) > 0) {
            if (e.and(BigInteger.ONE).equals(BigInteger.ONE)) {
                if (skipped > 0) {

                    if (skipped > 29) {
                        p = pow(p, BigInteger.ONE.shiftLeft(skipped));
                    } else {
                        p = p.pow(1 << skipped);
                    }
                    skipped = 0;
                }
                result = result.multiply(p);
            }
            skipped++;
            e = e.shiftRight(1);
            System.out.println(e);
        }
        return result;
    }

}

      

Note. The above implementation is really simple. This is most likely a solution that is more efficient in some cases, or uses modular operation to support "large" numbers. But you just cannot imagine (potentially) 34234534534222 decimal places unless you have 34 terabytes of RAM and an addressable JVM long

, so I doubt there will be a solution that fulfills the requirements you have stated so far - but will be reversed + generosity who proved i'm wrong ...

0


source







All Articles