L’altro giorno ci era capitato un problema strano: con il bigDecimal non e’ possibile definire esponenti frazionari, o piu’ specificatamente non riuscivamo con il Bigdecimal a definire radici superiori della quadra.
Premessa: un esponente 2/3 identifica di dover effettuare prima il quadrato dell’operando e successivamente la radice cubica del risultato.
Ci e’ venuta in soccorso la formula di Newton-Raphson
Bisogna cercare di definire un algoritmo che valuta ripetivamente l’espressione xi+1=xi-f(x)/f'(x). Il valore xi+1 e’ l’ultima approsimazione di una radice, xi e’ l’approssimazione precedente, f(x) e’ la funzione che adatta la radice e f'(x) e’ la sua derivata prima.
Kaplan focalizza questo concetto cercando la radice cubica di 17, si puo’ generalizzare questo risultato con qualsiasi numero per arrivare alla radice cubica.
Ecco l’espressione di Newton-Raphson
xi+1=xi-(xi3-n)/3xi2) che e’ esprimibile come dec x = x – ( x ^ 3 – n ) / ( “3” * x ^ 2 ) ;.
Ecco l’espressione in Java di quanto descritto precedentemente:
Listing 2. CubeRoot.java
// CubeRoot.infiqs
import java.math.*;
public class CubeRoot
{
// Maximum number of iterations performed by Newton-Raphson loop.
final static int MAXITER = 15;
public static void main (String [] args)
{
// Validate number of command line arguments.
if (args.length != 1)
{
System.err.println ("usage : java CubeRoot n");
System.err.println ("example: java CubeRoot 19");
System.err.println (" Find the cube root of 19");
return;
}
// Specify a math context with 40 digits of precision.
MathContext mc = new MathContext (40);
// Specify the number whose cube root is being sought.
BigDecimal n = new BigDecimal (args [0], mc);
// Specify the starting value in the search for the cube root.
BigDecimal x;
x=new BigDecimal("1",mc);
// Search for the cube root via the Newton-Raphson loop. Output each
// successive iteration's value.
for (int i = 0; i < MAXITER; i++)
{
x=x.subtract(x.pow(3,mc).subtract(n,mc).divide(new
BigDecimal("3",mc).
multiply(x.pow(2,mc),mc),mc),mc);
System.out.println (x);
}
}
}
Compila CubeRoot.java
e prova a verificare i risultati.
Per esempio invoca java CubeRoot 11.5
per comprendere come funziona l’algoritmo Newton-Raphson per trovare la radice di 11.5.
Si riesce a varificare che il risultato con almeno 40 decimali
2.257178717737000689722531351332293570729 si raggiunge in poche ripetizioni dell’algoritmo:
4.5
3.189300411522633744855967078189300411523
2.503065206710545285332351274464042799496
2.280542237899026579351609436198669505057
2.257417253127543076236357536600910449407
2.257178742941525167756167000357339173250
2.257178717737000971165927797364245467219
2.257178717737000689722531351332328663380
2.257178717737000689722531351332293570729
2.257178717737000689722531351332293570729
2.257178717737000689722531351332293570729
2.257178717737000689722531351332293570729
2.257178717737000689722531351332293570729
2.257178717737000689722531351332293570729
2.257178717737000689722531351332293570729
Fonti:
http://uclue.com/?xq=1608
http://www.javaworld.com/javaworld/jw-07-2006/jw-0724-funandgames.html?page=2