¿Cómo hacer una potencia fraccionaria en BigDecimal en Java?

En mi pequeño proyecto necesito hacer algo como Math.pow (7777.66, 5555.44) solo con MUY grandes números. Encontré algunas soluciones:

  • Usa doble, pero los números son muy grandes
  • Use BigDecimal.pow pero no soporte para fraccional
  • Usa la fórmula X ^ (A + B) = X ^ A * X ^ B (B es el rest del segundo num), pero de nuevo no admite X grande o grande porque todavía me convierto en doble
  • Use algún tipo de algoritmo de la serie Taylor o algo así – No soy muy bueno en matemáticas, así que esta es mi última opción si no encuentro ninguna solución (algunas bibliotecas o una fórmula para (A + B) ^ (C + D)).

¿Alguien sabe de una biblioteca o una solución fácil? Pensé que muchas personas enfrentan el mismo problema …

ps Encontré una biblioteca llamada ApFloat que dice que lo hace aproximadamente, pero los resultados que obtuve fueron tan aproximados que incluso 8 ^ 2 me dieron 60 …

La solución para los argumentos en 1.7976931348623157E308 (Double.MAX_VALUE) pero los resultados de apoyo con MILLONES de dígitos:

Dado que el doble admite números de hasta MAX_VALUE (por ejemplo, 100! En dobles 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 (rest 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 forma puede hacer lo siguiente (ignorar 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); 

Ejemplos de resultados:

 50!^10! = 12.50911317862076252364259*10^233996181 50!^0.06 = 7395.788659356498101260513 

Exponentes = logaritmos.

Eche un vistazo al Logaritmo de un BigDecimal