Operadores
double hipotenusa(double a, double b) {
return Math.sqrt((a * a) + (b * b));
}
> hipotenusa(3.0, 4.0)
> hipotenusa(1.0, 1.0)
5.0
1.4142135623730951
¿Recuerdas la fórmula para calcular el lado mayor de un triángulo rectángulo, su hipotenusa?
El Código 1 tiene una función que lo calcula.
Hasta ahora nos hemos ocupado principalmente de cadenas de Strings, pero para la hipotenusa presentamos nuestro primer tipo de dato numérico: double. Un double representa un número real (con algunas limitaciones) Para casos simples de números reales puedes usar un double. La función hipotenusa usa dos números reales que representan los lados del triángulo rectángulo y calcula la longitud del otro lado.
Para la implementación usamos algunos operadores y otra función de la librería estándar: Math.sqrt(). Esta función calcula la raíz cuadrada de un número. Recibe un double y retorna un double.
Como argumento utilizamos dos operadores: «*» para multiplicar números y«+» para sumar números. Estos operadores también están disponibles con otros tipos numéricos.
Para escribir valores necesitas usar literales: 3.0, 4.0 y 1.4142. Estos son literales para tipo doubles, dado que tienen un punto.
Tipos Primitivos
Java viene con algunos tipos definidos que se denominan primitivos para representar tipos básicos: caracteres, números y predicados. Estos son los más importantes:
| Palabra Clave | Que representa | Ejemplo Literal |
|---|---|---|
char |
Caracteres Unicode | 'A', 'a', '1', ' ', 'ó', '@',
etc. |
boolean |
Predicados | true, false |
int |
Enteros | 1, -17, 123_000, etc. |
double |
Numeros Reales | 1.4142, -123.0, 0.0, etc. |
Ya conocíamos los String que no son datos primitivos, pero que también tienen literales como
"Hola Mundo!"
Operadores
Así como ya tenemos algunos tipos primitivos, Java tiene algunos operadores que podemos usar. Los operadores más comunes son:
Operadores Numéricos
Estos operadores se pueden utilizar con tipos numéricos como int y double. Toman dos valores del mismo tipo y devuelven un valor de ese mismo tipo, p.j. si sumas dos números enteros devuelven un número entero, si multiplicas dos double devuelve un double.
| Simbolo | Operacion | Ejemplo |
|---|---|---|
| + | adición | a + b, x + 1, etc |
| - | sustracción | a - b, j - 2, etc |
| * | multiplicación | a * b, x * 10, etc |
| / | división | a / b, m / 5, etc |
| % | módulo | a % b, n % 2, etc. |
El operador de módulo devuelve el residuo después de la división de los dos números.
int siguiente(int número) {
return número + 1;
}
> siguiente(9)
> siguiente(33)
10
34
int agregar0(int número) {
return número * 10;
}
> agregar0(55)
> agregar0(123)
550
1230
int rangoInclusivo(int inicio, int fin) {
// retorna la cantidad de números entre fin e inicio
// incluyendo los extremos
return fin - inicio + 1;
}
> rangoInclusivo(3, 10)
> rangoInclusivo(100, 102)
8
3
Operadores de Relación
Estos operadores se pueden utilizar con tipos numéricos como int y double. Toman dos números del mismo tipo y devuelven un valor booleano.
| Simbolo | Operacion | Ejemplo |
|---|---|---|
| < | Menor que | a < b, x < 0.0, etc |
| <= | Menor o igual | a <= b, longitud <= 1.0, etc. |
| > | Mayor que | a > b, residuo > 0.0, etc. |
| >= | Mayor o igual | a <= b, (a + 1) <= b, etc. |
| == | Igual | a == b, cantidad == 1, etc. |
| != | Diferente | a != b, n != 0, etc. |
boolean esMayorDeEdad(int edad) {
// la mayoría de edad es a partir de los 18
return edad >= 18;
}
> esMayorDeEdad(17)
> esMayorDeEdad(18)
> esMayorDeEdad(31)
false
true
true
boolean exentoDeImpuesto(double precio) {
// si el precio es menos de $1.000.000 no paga impuesto
return precio < 1_000_000.0;
}
> exentoDeImpuesto(150_000)
> exentoDeImpuesto(2_300_000)
true
false
boolean esMúltiplo(int a, int b) {
return (a % b) == 0;
}
> esMúltiplo(30, 2)
> esMúltiplo(100, 3)
true
false
esMúltiplo() es una función que toma dos números enteros y devuelve un valor booleano: «true» si a es múltiplo de b o «false» en caso contrario. Utiliza el operador del módulo para verificar si el residuo de dividir «a» y «b» es «0», que es la definición de ser múltiplo. Podemos usar varios operadores en una misma expresión, así sea de tipos distintos.
El uso más común del operador % es para revisar si un número es múltiplo de otro.
Operadores Lógicos
La mayoría de estos operadores toman dos predicados y devuelven otro predicado. Sólo el operador negación toma un solo predicado. Se utilizan para obtener predicados más complejos a partir de otros predicados. El resultado de estos operadores se muestra después de ellos:
| Simbolo | Operacion | Ejemplo |
|---|---|---|
| && | Y Lógico | a && b, a > 0 && a > 10, etc. |
| || | O Lógico | a || b, (a != b || b == 10), etc |
| ! | Negación | !contiene, etc |
Tabla lógica del operador Y
| a | b | a && b |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
El resultado del Y lógico sólo puede resultar en verdadero cuando ambos operandos son verdaderos.
Tabla Lógica del operador O
| a | b | a || b |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
El resultado del O lógico sólo puede resultar en falso cuando ambos operandos son falsos.
Tabla lógica del operador negación
| n | !n |
|---|---|
| true | false |
| false | true |
boolean esMayorDeEdad(int edad) {
return edad >= 18;
}
boolean esAdultoMayor(int edad) {
return edad >= 60;
}
boolean esAdulto(int edad) {
return esMayorDeEdad(edad) && !esAdultoMayor(edad);
}
> esAdulto(24)
> esAdulto(81)
true
false
boolean esMúltiplo(int a, int b) {
return (a % b) == 0;
}
boolean esAñoBisiesto(int year) {
return esMúltiplo(year, 4) &&
(esMúltiplo(year, 400) || !esMúltiplo(year, 100));
}
> esAñoBisiesto(1900)
> esAñoBisiesto(2000)
> esAñoBisiesto(2024)
false
true
true
esAñoBisiesto() toma un número entero y devuelve verdadero si ese año es o será bisiesto. Un año bisiesto debe ser múltiplo de 4 y tener una de dos condiciones más: ser múltiplo de 400 o no ser múltiplo de 100. Nuevamente, usamos la función que escribimos antes esMúltiplo() para mejorar la legibilidad del código.
Operador Ternario
double max(double a, double b) {
return (a > b) ? a : b;
}
> max(3.0, 5.0)
5.0
La mayoría de los operadores son binarios, lo que significa que operan sobre dos valores, como la suma. En matemáticas y lógica también existen operadores unarios que utilizan un solo valor. El operador negación en programación es un operador unario. Resulta que en programación existe un operador ternario de esta forma:
<predicado> ? <valor1> : <valor2>
El resultado del operador se basa en el predicado, si la expresión es verdadera se evalúa como el «primer» valor, el que está entre «?» y «:», si es falso, se evalúa como el «segundo» valor, el que está después de «:» Ambos valores deben ser del mismo tipo.
Para la función «max()» en el Código 10, el preciado es «a > b». Si eso se evalúa como verdadero, entonces el valor de toda la expresión es el parámetro «a» ; de lo contrario, el valor es el parámetro «b». El predicado puede ser tan complejo como se necesite, y las otras partes también pueden ser tan complejas como se desee, aunque probablemente sea mejor mantenerlas simples.
Podrías pensar que es extraño tener un operador como el operador ternario, pero resulta que hay muchas oportunidades para usarlo y que tu código sea conciso pero muy legible.
Misión secundaria: consideraciones con números reales
Los números reales son difíciles de representar en las computadoras. A las variables se les asigna una cantidad de bits para ser representadas, pero muchos números reales tienen infinitos dígitos decimales como ⅓. Dado que las computadoras sólo pueden tener una representación limitada de dichos números, debes tener cuidado al usarlos en tu código. Si tienes varias operaciones con números reales, es probable que el número sea ligeramente diferente de lo esperado. En algunos casos, estos podrían no ser importantes, pero en otros, como el dinero, sería inconveniente y se debería utilizar otra alternativa. Dichas alternativas se salen del alcance de este material, pero es bueno que conozcas las limitaciones de los tipos de datos primitivos en un lenguaje.
Normalmente se prefiere evitar el uso de un operador como == para comprobar números
reales. Debido a las imprecisiones de las que hemos hablado, solemos comprobarlas con un
delta. Por ejemplo para comprobar si una variable
Math.abs(n - 1.0)< 1e-3
En este caso «1e-3» es otro posible literal para números reales, y expresarlos en algo parecido a una notación científica y en este caso es igual a 10-3 es decir 0,001.
Aquí hay una tabla de números en notación científica y la manera en que los puedes escribir en programación:
| 1 x 10-1 | 1e-1 |
| 1 x 10-2 | 1e-2 |
| 1 x 105 | 1e-5 |
| 6.6743 x 10-11 | 6.6743e-11 |
| 6.6378 x 106 | 6.378e-6 |
Entonces, en el código anterior estás verificando que «n» sea igual a 1.0 hasta los primeros 2 números digitales. Esto suele aceptarse cuando se trata de longitudes, ya que diferencias más pequeñas son imperceptibles para el ojo humano.
Diferentes dominios requerirán diferentes deltas, así que no asumas que siempre puedes usar el mismo delta. Cuando utilices un dominio, aprende qué es importante en él y elige el delta con esa información. Como se indicó anteriormente, para las medidas 1e-3 probablemente sería suficiente.
Diversión con funciones
¿Dónde puedes usar una función que retorne un valor? En cualquier lugar donde se espere un valor. De hecho, una función pura es en realidad otra forma de representar su valor devuelto.
Escribamos algunas funciones:
double adición(double a, double b) {
return a + b;
}
double multiplicación(double a, double b) {
return a * b;
}
double cuadrado(double n) {
return multiplicación(n, n);
}
Ahora podemos reimplementar la hipotenusa() como por ejemplo:
double hipotenusa(double a, double b) {
return Math.sqrt(adición(cuadrado(a), cuadrado(b)));
}
Esa implementación tiene muchos paréntesis pero es una expresión válida. Diferentes programadores argumentarán que la última versión de la hipotenusa es más o menos legible que la que vimos inicialmente en este capítulo, pero lo importante es recordar que puedes llamar funciones en cualquier lugar donde puedas usar un valor.
Resumen
Los lenguajes de programación ofrecen diferentes tipos de datos primitivos. En Java los más comunes son:
- boolean: para predicados
- char: para caracteres Unicode
- int : números enteros
- double: números reales
- String: cadenas de caracteres
Si deseas representar valores de estos tipos de datos, puedes utilizar sus literales:
- boolean: «true»,«false»
- char: un solo caracter entre comillas sencillas
- int: digitos sin caracter de punto
- double: dígitos con un punto
- String: cero o más caracteres entre comillas dobles "
Además de funciones, los lenguajes incluyen operadores que puedes utilizar para operaciones que son muy comunes. Los operadores están definidos para algunos tipos y tienen un tipo de devolución específico. Lo más importante que debes recordar es que, si operas con dos valores, el resultado será del mismo tipo, ¡La división de dos enteros también será un entero!
Operadores
Quiz Interactivo
Antes de intentar los ejercicios, toma unos minutos para verificar tu entendimiento de Operadores tomando este quiz.
- Las preguntas y el orden de las opciones son diferentes cada vez que tomes el quiz.
- Las preguntas que tengas mal, vuelven a aparecer luego hasta que las contestes correctamente.
- Cada pregunta tiene una pista y una explicación.
Ejercicios
Errores del compilador y de ejecución
Escribe los siguientes códigos y lee el error que te devuelve el compilador o el ambiente de ejecución. Después escribe el código correcto.
int multiplicación(String número1, String número2) {
return número1 * número2;
}
int suma(int número1, int número2) {
return + número1 número2;
}
boolean positivoMenorDe20(int número) {
return número > 0 && > 20;
}
Ejercicios de Codificación
E2.4
Llena el hueco de la función truncar, de modo que dado un número entero, retorne el mismo número pero sin su último dígito. Revisa los ejemplos para más claridad.
int truncado(int n) {
return n ___ 10;
}
> truncado(123)
> truncado(456)
> truncado(9)
> truncado(0)
12
45
0
0
E2.5
Llena el hueco de la función últimoDígito, de modo que dado un número entero, retorne el último dígito de este. Revisa los ejemplos para más claridad
int últimoDígito(int n) {
return n ___ 10;
}
> últimoDígito(123)
> últimoDígito(456)
> últimoDígito(9)
> últimoDígito(0)
3
6
9
0
E2.6
Llena los huecos, para crear una función que dado un número entero, devuelve «true» si el número está dentro del rango de 0 a 9 y «false» de lo contrario. Revisa los ejemplos para más claridad.
___ únicoDígito(int n) {
return (n ___ 0) ___ (n ___ 10);
}
> únicoDígito(0)
> únicoDígito(1)
> únicoDígito(5)
> únicoDígito(9)
> únicoDígito(10)
> únicoDígito(88)
true
true
true
true
false
false
E2.7
Llena los huecos, para crear una función que dado un número entero, devuelva el String "no-negativo" si es positivo o cero, o "negativo" si es negativo.
String signo(int n) {
return (n >= 0) ___ "no-negativo" ___ "negativo";
}
E2.8
Escribe una función esPar() que verifique si un número es par. Un número es par si es múltiplo de 2.
> esPar(2)
> esPar(13)
true
false
E2.9
Escribe una función esImpar() que verifique si un número es impar. Un número es impar si no es par.
> esImpar(2)
> esImpar(13)
false
true
E2.10
Escriba una función, diferenciaDeCuadrados() que tome dos números enteros y devuelva el resultado de a2 - b2.
> diferenciaDeCuadrados(3,2)
> diferenciaDeCuadrados(1,1)
5
0
E2.11
Escribe una función, tercerÁngulo() que tome dos doubles que representan la medida de dos ángulos de un triángulo y devuelva la medida del tercero. Los 3 ángulos de un triángulo suman 180.0, por lo que si restas la suma de dos ángulos a 180.0 deberías obtener el tercer ángulo.
> tercerÁngulo(60.0, 60.0)
> tercerÁngulo(45.0, 90.0)
> tercerÁngulo(35.0, 50.0)
60.0
45.0
95.0
E2.12
Escribe una función que tome un número entero y devuelva un predicado que sea «true» si es un múltiplo positivo de siete y es menor que 1000, «false».
> validarMúltiploDe7(-7)
> validarMúltiploDe7(0)
> validarMúltiploDe7(91)
> validarMúltiploDe7(9100)
false
false
true
false
E2.13
Escribe una función validar() que tome tres números enteros: inicio, mitad y tamaño y retorne verdadero si <inicio> es mayor o igual a 0, <inicio> es menor que <mitad> y <mitad> es menor que tamaño.
> validar(0, 1, 2)
> validar(1, 1, 2)
> validar(2, 1, 3)
> validar(0, 3, 3)
> validar(1, 3, 5)
true
false
false
false
true
E2.14
Un parqueadero abre a las 8:00 am y cierra a las 6:00 pm. Su sistema de cobro es el siguiente: el usuario paga $10.0 por cada minuto de parqueo, pero tiene un cobro mínimo de $100.0 y tiene un cobro máximo de $3000.0. Haz una función cobro() que retorne un número double siendo el cobro a un usuario, dado un número entero que representa los minutos que estuvo su vehículo en el parqueadero.
Para hacer esta función puedes utilizar estos 2 métodos de la clase Math:
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Math.html#min(double,double)
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Math.html#max(double,double)
> cobro(1)
> cobro(10)
> cobro(15)
> cobro(90)
> cobro(1_000)
100.0
100.0
150.0
900.0
3000.0
Ejercicios de Corrección de Código
Para estos problemas, mira los ejemplos de uso de una función y luego revisa el código inicial que no está funcionando como se espera. Ejecútalo y luego corrígelo para coincidir con los ejemplos.
> inicio(6, 1)
> inicio(6, 2)
> inicio(6, 3)
> inicio(10, 2)
0
6
12
10
int inicio(int resultados, int página) {
return (resultados * página) - 1;
}
© 2022 Carlos Obregón. This work is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0)