La solución para los argumentos bajo 1.7976931348623157E308 (Double.MAX_VALUE) pero los resultados de apoyo con millones de dígitos:
Puesto que los números dobles soporta hasta MAX_VALUE (por ejemplo, 100! en doble se ve así: 9.332621544394415E157), no hay ningún problema para utilizar BigDecimal.doubleValue(). Pero no deberías hacer Math.pow (doble, doble) porque si el resultado es mayor que MAX_VALUE obtendrás el infinito. SO: use la fórmula X^(A + B) = X^A * X^B para separar el cálculo en DOS potencias, la grande, usando BigDecimal.pow, y la pequeña (resto del 2 ° argumento), usando Math. pow, luego multiplicar X se copiará en DOBLE - asegúrese de que no sea más grande que MAX_VALUE, A será INT (máximo 2147483647 pero BigDecimal.pow no admite enteros más de mil millones de todos modos), y B será doble, siempre menos de 1. de esta manera usted puede hacer lo siguiente (caso omiso de mis constantes privadas, 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);
Resultados ejemplos:
50!^10! = 12.50911317862076252364259*10^233996181
50!^0.06 = 7395.788659356498101260513
Podría dar un ejemplo de lo que se intenta lograr, 8^2 = 64 sonidos pobre y 2^100^100 necesita ser reducido. – stacker
Debo decir que probé el truco de la fórmula, ¡y hasta ahora funciona bien incluso con números con millones de dígitos! (Parece que no sé todo sobre double e int) ... Ejemplos: 50!^10! = 12.50911317862076252364259 * 10^233996181 50!^0.06 = 7395.788659356498101260513 El código es un poco largo para publicar aquí, pero se obtiene la idea de X^(A + B) = X^A * X^B ... Ahora Estoy tratando de entender cómo y por qué (y si) realmente funciona con números tan grandes. –
Ya he dado la solución allí http://stackoverflow.com/questions/11848887/bigdecimal-to-the-power-of-bigdecimal-on-java-android/22556217#22556217 –