La soluzione per gli argomenti sotto 1.7976931348623157E308 (Double.MAX_VALUE), ma i risultati che sostengono con milioni di cifre:
Dato che i numeri doppi supporta fino a MAX_VALUE (ad esempio, 100! in double appare così: 9.332621544394415E157), non c'è alcun problema nell'usare BigDecimal.doubleValue(). Ma non dovresti semplicemente eseguire Math.pow (double, double) perché se il risultato è maggiore di MAX_VALUE otterrai solo l'infinito. SO: usa la formula X^(A + B) = X^A * X^B per separare il calcolo in DUE poteri, il grande, usando BigDecimal.pow, e il piccolo (resto del secondo argomento), usando Math. pow, quindi moltiplicare. X verrà copiato in DOUBLE - assicurati che non sia più grande di MAX_VALUE, A sarà INT (massimo 2147483647 ma BigDecimal.pow non supporta integer più di un miliardo in ogni caso), e B sarà doppio, sempre meno di 1. in questo modo è possibile effettuare le seguenti (ignorare i miei costanti privati 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);
Risultati esempi:
50!^10! = 12.50911317862076252364259*10^233996181
50!^0.06 = 7395.788659356498101260513
fonte
2010-08-28 10:05:50
può fare un esempio di ciò che si tenta di realizzare, 8^2 = 64 suoni povero e 2^100^100 deve essere ridimensionato. – stacker
Devo dire che ho provato il trucco della formula, e funziona fino ad ora anche con numeri con milioni di cifre! (Sembra che io non sappia tutto su double e int) ... Esempi: 50!^10! = 12.50911317862076252364259 * 10^233996181 50!^0.06 = 7395.788659356498101260513 Il codice è un po 'lungo da postare qui, ma si ha l'idea di X^(A + B) = X^A * X^B ... Ora Sto cercando di capire come e perché (e se) funziona davvero con numeri enormi. –
Ho già dato la soluzione lì http://stackoverflow.com/questions/11848887/bigdecimal-to-the-power-of-bigdecimal-on-java-android/22556217#22556217 –