Los métodos de la clase Math de Java son funciones preprogramadas que nos ayudan a realizar determinadas operaciones de una forma más sencilla, por ejemplo si queremos el cuadrado de un número utilizaríamos el método "pow", el cual recibe dos parámetros, el primero es el número que queremos elevar a cierta potencia y el segundo es precisamente la potencia, en este caso para el cuadrado la potencia es 2, esto es así:
int num = 3;
int cuadrado = Math.pow(num, 2);
La variable "cuadrado" valdrá 9 ya que internamente Math.pow toma el número que le pasamos (num), lo eleva a la potencia que le indicamos (2) y nos devuelve el resultado.
■ Poniendo a prueba nuestra lógica
Pero ¿si quisieramos hacerlo manualmente?, tendríamos que pensar en cómo realizaríamos las operaciones para conseguir el mismo resultado, hacer esto supondría un buen ejercicio pues nos obliga a comprender qué es lo que está sucediendo y pensar de qué forma podemos llegar a dicho resultado, veamos algunos casos.
• Math.abs(double)
"abs" es una función de Math que devuelve el valor absoluto de un número, pero, ¿qué es el valor absoluto?, el valor absoluto de un número es la distancia que hay entre el número y el cero sin importar si el número es positivo o negativo, por ejemplo los números -6 y 5, veamos la siguiente recta numérica:
La distancia entre 5 y 0 es 5 ya que hay 5 unidades entre 5 y 0.
Podríamos decir que el valor absoluto de un número es el propio número pero siempre positivo y eso es precisamente lo que devuelve Math.abs(número).
int absoluto;
absoluto = Math.abs(-13); // Devolverá 13
absoluto = Math.abs(10); // Devolverá 10
Si quisiéramos hacer una función propia que devuelva el valor absoluto de un número obviamente sin usar Math.abs, ¿cómo lo haríamos?.
Analizando el problema
Si el valor absoluto de un número es el mismo número pero positivo significa que:
- El valor absoluto de un número positivo es el propio número.
- El valor absoluto de un número negativo es el mismo número pero con el signo contrario, es decir, de negativo lo pasamos a positivo.
Entonces ¿cómo programaríamos eso?
Como siempre, en programación hay muchas soluciones y una de ellas podría ser:
1) Preguntar si el número es positivo o negativo.
2) Si el número es positivo, su valor absoluto es el mismo número.
3) Si el número es negativo lo multiplicaríamos por -1 para convertirlo a positivo y ese sería su valor absoluto.
Programando lo anterior:
public static double Absoluto(double numero) {
double valor_absoluto;
if (numero > -1) {
valor_absoluto = numero;
} else { // Si el número es negativo
valor_absoluto = numero * -1; // Se convierte a positivo
}
return valor_absoluto;
}
Listo, ya tenemos una función propia que emula a Math.abs, recibe un número entero o decimal y regresa su valor absoluto.
int absoluto;
absoluto = Absoluto(-3); // Devuelve 3.0
absoluto = Math.abs(-3); // Devuelve 3
Ambas devuelven 3.
• Math.round(double)
Esta función lo que hace es redondear un número a su valor más cercano ya sea superior o inferior, por ejemplo si le pasamos 4.4 lo redondea a 4 y si le pasamos 4.6 lo redondea a 5, esto funciona como se muestra en la imagen de abajo:
Analizando el problema
Si la función "round" redondea dependiendo de los decimales de esta forma:
Para los números positivos:
Para los números positivos:
- Si los decimales del número terminan en .49 o menor, es decir, no llega a .5 lo redondea hacia el siguiente entero inferior.
- Si los decimales del número terminan en .5 o superior lo redondea hacia el siguiente entero superior.
Para los números negativos:
- Si los decimales del número son menores que 0.5, el número se redondea hacia sí mismo, es decir, si el número es -3.4, redondeado sería -3.
- Si los decimales del número son menores que 0.5, el número se redondea hacia sí mismo, es decir, si el número es -3.4, redondeado sería -3.
- Si los decimales son 0.5 o superior, el número se redondea al siguiente entero, por ejemplo si el número es -3.5, redondeado sería -4.
Partiendo de lo anterior, ¿cómo lo haríamos?
Una forma podría ser la siguiente:
1) Preguntar si el número es positivo o negativo.
2) Si es negativo:
- Primero obtenemos el residuo del número pero tratándolo como si fuera positivo.
- Luego evaluamos el residuo, si es menor a 0.5, entonces el número redondeado sería el propio número convertido a entero.
- Si el residuo es 0.5 o mayor, convertimos el número a entero y le restamos 1.
3) Si es positivo:
- Primero obtenemos directamente su residuo.
- Luego si el residuo es menor a 0.5, el número redondeado sería el propio número convertido a entero.
- Si el residuo es 0.5 o mayor, el número redondeado es el mismo número convertido a entero y sumándole 1.
Con "convertir a entero" entiéndase que el número decimal al ser pasado a entero pierde sus decimales, es decir, si el número es 2.5 y se convierte a entero queda solo el 2, si el número es -3.3 y se convierte a entero queda solo el -3, es decir, al convertir a entero solo queda la parte entera del número.
¿Cómo hacemos esto en Java?
Simplemente anteponemos (int) al número:
Simplemente anteponemos (int) al número:
double n1 = 3.3;
int n2 = (int)n1;
System.out.println(n2); // Mostrará 3
A esto se le llama "cast" o "castear" el número, como si le dijéramos al número "sé que eres un double pero te vas a comportar como entero".
Programando lo anterior:
public static int redondear(double numero) {
int redondeado;
double residuo;
if (numero < 0) {
residuo = (numero * -1) % 1;
if (residuo < 0.5) {
redondeado = (int)numero;
} else {
redondeado = (int)numero - 1;
}
} else {
residuo = numero % 1;
if (residuo < 0.5) {
redondeado = (int)numero;
} else {
redondeado = (int)numero + 1;
}
}
return redondeado;
}
Hecho esto ya tenemos una función propia que se comporta igual que Math.round donde ambas funcionan de la siguiente forma:
double redondeado;
redondeado = redondear(4.2); // Devuelve 4
redondeado = Math.round(4.2); // Devuelve 4
redondeado = redondear(4.6); // Devuelve 5
redondeado = Math.round(4.6); // Devuelve 5
redondeado = redondear(-4.6); // Devuelve -5
redondeado = Math.round(-4.6); // Devuelve -5
• Math.max(int/double, int/double)
Esta función es muy simple, recibe dos números y devuelve el mayor, y si son iguales solo devuelve uno de ellos.
Analizando el problema
Creo que en este caso no hay mucho que pensar, la cosa es así:
1) Se reciben dos números y si son iguales se deveuelve uno de ellos.
2) Si son diferentes se pregunta cuál es el mayor y ese es el que se devuelve.
Programando lo anterior:
public static double Mayor(double n1, double n2) {
double mayor;
if (n1 == n2) {
mayor = n1;
} else if (n1 > n2) {
mayor = n1;
} else {
mayor = n2;
}
return mayor;
}
Listo, tenemos una función que nos regresa el mayor de dos números, sean enteros o decimales.
int nMayor;
nMayor = Mayor(4, 7); // Devolverá 7.0
nMayor = Math.max(4, 7); // Devolverá 7
Ambos devolverán 7.
• Math.pow(int/double, int/double)
Esta es una función que recibe dos números y lo que hace es elevar el primero a la potencia que indique segundo. Como ya se había mencionado al inicio, si quisiera elevar 3 al cuadrado usando Math.pow(base, potencia) le pasaría los números 3 y 2, donde 3 es el número a elevar (base) y 2 representa al cuadrado (potencia).
Analizando el problema
Sabemos que si se quiere elevar un número m a una potencia n una forma es multiplicar n-1 veces el número m por sí mismo, por ejemplo:
Si m = 2 y n = 2 la multiplicación sería → m * m
Si m = 2 y n = 3 entonces sería → m * m * m
Pero, ¿qué pasa si la potencia es negativa?
Por ejemplo 2⁻² es 0.25.
¿Cómo obtenemos eso?, la respuesta es dividiendo el número entre sí mismo n+1 veces (condierando a n como positivo), esto es:
Si m = 2 y n = -2, entonces la división sería → m / m / m / m
Si m = 2 y n = -3, entonces sería → m / m / m / m / m
Considerando esto, ¿cómo lo haríamos?
Algo así:
1) Primero preguntamos si el número base es mayor que 0.
2) Preguntamos si la potencia es igual a 0, si es así regresamos 1.
3) Si la potencia no es 0 preguntamos si es mayor a 0.
4) Si la potencia es mayor a 0 entonces se multiplica el número por si mismo el mismo número de veces que valga la potencia - 1, ejemplo si la potencia es 3 se multiplica dos veces, n * n * n.
5) Si la potencia es menor que 0, en lugar de multiplicar se divide el número entre sí mismo el mismo número de veces que vale la potencia convertida a positiva + 1, ejemplo si la potencia es -3 se dividiría 4 veces, n / n / n / n / n.
Programando lo anterior:
public static double Potencia(double base, double potencia) {
double resultado = 0;
if (base > 0) {
if (potencia == 0) {
resultado = 1;
} else if (potencia > 0) {
resultado = base;
for (int i=1; i < potencia; i++) {
resultado = resultado * base;
}
} else {
resultado = base;
for (int i=0; i < ((potencia * -1) + 1); i++) {
resultado = resultado / base;
}
}
}
return resultado;
}
Así tenemos una función propia que nos regresa un número elevado a la potencia que le indiquemos, igual que Math.pow().
int potencia;
potencia = Potencia(2, 3); // Devolverá 8.0
potencia = Math.pow(2, 3); // Devolverá 8
potencia = Potencia(2, -3); // Devolverá 0.125
potencia = Math.pow(2, -3); // Devolverá 0.125
Ambos regresan 8.
■ Conclusión
Las funciones preprogramadas del lenguaje nos ayudan a resolver situaciones comunes como lo es elevar un número al cuadrado, obtener su raíz, redondearlo, etc., haciendo uso de ellas nos ahorramos tener que codificarlas nosotros mismos sin embargo cuando se está aprendiendo intentar emularlas puede ser un buen ejercicio de lógica ya que debemos pensar en una solución que nos lleve al mismo resultado.
No hay comentarios:
Publicar un comentario