some image

Codes and Tags

Raíz cuadrada Newton – Raphson en Java con Bigdecimal

Etiquetas: , Blog, Programación No comments

Este Post esta dedicado a Phicar y Voodoo, quienes fueron los que implantaron el origen de la duda la cual me ha llevado a pensar en esta posible implementación del método :).

1) ¿Qué es el método de Newton – Raphson?

Según la wiki : En análisis numérico, el método de Newton (conocido también como el método de Newton-Raphson o el método de Newton-Fourier) es un algoritmo eficiente para encontrar aproximaciones de los ceros o raíces de una función real. También puede ser usado para encontrar el máximo o mínimo de una función, encontrando los ceros de su primera derivada.

En este enlace, podrán encontrar una demostración bastante buena sobre las deficiencias y ventajas del método, así como su implementación matemática.

2) ¿Porqué utilizar el método de Newton – Raphson para obtener la raiz cuadrada?

a) Para realizar la demostración de método numérico planteado.
b) Porqué para operar con BigDecimal no existe un método implementado para obtener raíz cuadrada (sqrt).
c) Porqué puede ser muy útil en las maratones de programación.
d) Para jugar un rato con la programación y las matemáticas.

3) Código

/**
 * Esta clase muestra un ejemplo del como obtener una raiz cuadrada, basandose
 * en el metodo de NewtonRaphson. La implementacion de este numero  
 * @author codesandtags
 * 
 *         Explicacion del metodo NewtonRaphson Referencias :
 *         http://es.scribd.com/doc/15638680/Metodo-de-NewtonRaphson
 * 
 */
public class NewtonRaphsonBigDecimal {

	public static void main(String[] args) throws IOException {

		// Objeto para lectura por teclado
		BufferedReader input = new BufferedReader(new InputStreamReader(
				System.in));
		// Variables
		double numero = 0.0;
		String numeroBig = null;
		int precision = 0;

		// Instancia a la clase
		NewtonRaphsonBigDecimal resultado = new NewtonRaphsonBigDecimal();

		System.out.println(" ------ Calculando raices double -------");
		// Numero a calcular
		System.out.print("\nIngrese numero : ");
		numero = Double.parseDouble(input.readLine());
		// Precision de la raiz
		System.out.print("Ingrese precision : ");
		precision = Integer.parseInt(input.readLine());

		// Se obtiene la raiz
		System.out.println("Raiz : " + resultado.getRaiz(numero, precision));

		// Haciendo magia con 5 numeros aleatorios
		for (int i = 0; i < 5; i++) {
			numero = Math.floor(Math.random() * 500);
			precision = (int) Math.floor(Math.random() * 15 + 1);
			System.out
					.println("Raiz : " + resultado.getRaiz(numero, precision));
		}

		System.out
				.println("\n ------ Calculando raices double BigDecimal -------");
		// Numero a calcular
		System.out.print("\nIngrese numero gigante : ");
		numeroBig = input.readLine();
		// Precision de la raiz
		System.out.print("Ingrese precision : ");
		precision = Integer.parseInt(input.readLine());

		// Se obtiene la raiz
		System.out.println("Raiz : "
				+ resultado.getRaizBigDecimal(numeroBig, precision));

	}

	/**
	 * Obtiene una raiz con el metodo de Newton - Raphson, teniendo en cuenta la
	 * precision de la raiz a obtener
	 * 
	 * Formula = raiz - (raiz^2 - numero) / (2 * raiz)
	 * 
	 * @param numero
	 * @param precision
	 * @return
	 */
	public double getRaiz(double numero, int precision) {
		System.out.println("\nObteniendo raiz cuadrada para el numero [" + numero
				+ "] y precision + [" + precision + "]");
		if (numero <= 0) {
			System.err.println("ERROR : No se puede obtener raices negativas");
			return 0;
		}

		double raiz = 1;
		for (int i = 0; i < precision; i++) {
			raiz = raiz - (Math.pow(raiz, 2) - numero) / (2 * raiz);
		}

		return raiz;
	}

	/**
	 * Obtiene una raiz con el metodo de Newton - Raphson para numberos
	 * BigDecimal, teniendo en cuenta la precision de la raiz a obtener
	 * 
	 * Formula = raiz - (raiz^2 - numero) / (2 * raiz)
	 * 
	 * @param numero
	 * @param precision
	 * @return
	 */
	public String getRaizBigDecimal(String numero, int precision) {
		System.out.println("\nObteniendo raiz cuadrada Bigdecimal para el numero ["
				+ numero + "] y precision + [" + precision + "]");

		BigDecimal bigNumero = new BigDecimal(numero);
		BigDecimal raiz = BigDecimal.ONE;
		BigDecimal raizTemp = null;

		if (bigNumero.compareTo(BigDecimal.ZERO) < 1) {
			System.err.println("ERROR : No se puede obtener raices negativas");
			return "0";
		}

		for (int i = 0; i < precision; i++) {
			// Se guarda el valor temporal de la raiz para operar mas adelante
			raizTemp = raiz;

			// Factor a = (raiz^2 - 2)
			raiz = raiz.pow(2).subtract(bigNumero);
			// Factor b = Factor a / (2 * raiz)
			// Aqui se utiliza RoundingMode.HALF_UP, para evitar valores
			// infinitos y la excepcion generada en tiempo de ejecucion
			// "Non-terminating decimal expansion no exact representable
			// decimal result" y 10 decimales
			raiz = raiz.divide(raizTemp.multiply(BigDecimal.valueOf(2)), 10,
					RoundingMode.HALF_UP);
			// raiz - Factor b
			raiz = raizTemp.subtract(raiz);
		}

		return raiz.toString();
	}

}

4) Salida

 ------ Calculando raices double -------

Ingrese numero : 85296325874125896325874125896465
Ingrese precision : 100

Obteniendo raiz cuadrada para el numero [8.52963258741259E31] y precision + [100]
Raiz : 9.235601002323882E15

Obteniendo raiz cuadrada para el numero [427.0] y precision + [6]
Raiz : 20.748088791061598

Obteniendo raiz cuadrada para el numero [181.0] y precision + [12]
Raiz : 13.45362404707371

Obteniendo raiz cuadrada para el numero [138.0] y precision + [7]
Raiz : 11.747340132123018

Obteniendo raiz cuadrada para el numero [177.0] y precision + [15]
Raiz : 13.30413469565007

Obteniendo raiz cuadrada para el numero [194.0] y precision + [12]
Raiz : 13.92838827718412

 ------ Calculando raices double BigDecimal -------

Ingrese numero gigante : 852963258741258963258741258964658529632587412589632587412589646565465456465464
Ingrese precision : 250

Obteniendo raiz cuadrada Bigdecimal para el numero [852963258741258963258741258964658529632587412589632587412589646565465456465464] y precision + [250]
Raiz : 923560100232388213395499100296508317192.4280825418

About Edwin Torres

Related Posts

  • Logo Java
  • Logo Java
  • Logo Java
  • Logo Java

Add your comment