java formula bigdecimal pow

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



formula pow (2)

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 resto 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 (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 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