Operadores

Código 1 - hipotenusa, usando tipos doubles y algunos operadores
double hipotenusa(double a, double b) {
   return Math.sqrt((a * a) + (b * b));
}
Input
> hipotenusa(3.0, 4.0)
> hipotenusa(1.0, 1.0)
Output
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.

Código 2 - Operador +
int siguiente(int número) {
  return número  +  1;
}
Input
> siguiente(9)
> siguiente(33)
Output
10
34
Código 3 - Operador *
int agregar0(int número) {
  return número * 10;
}
Input
> agregar0(55)
> agregar0(123)
Output
550
1230
Código 4 - Operador -
int rangoInclusivo(int inicio, int fin) {
  // retorna la cantidad de números entre fin e inicio
  // incluyendo los extremos
  return fin - inicio + 1;
}
Input
> rangoInclusivo(3, 10)
> rangoInclusivo(100, 102)
Output
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.
Código 5 - Operador >=
boolean esMayorDeEdad(int edad) {
  // la mayoría de edad es a partir de los 18
  return edad >= 18;
}
Input
> esMayorDeEdad(17)
> esMayorDeEdad(18)
> esMayorDeEdad(31)
Output
false
true
true
Código 6 - Operador <
boolean exentoDeImpuesto(double precio) {
  // si el precio es menos de $1.000.000 no paga impuesto
  return precio < 1_000_000.0;
}
Input
> exentoDeImpuesto(150_000)
> exentoDeImpuesto(2_300_000)
Output
true
false
Código 7 - Operador == <
boolean esMúltiplo(int a, int b) {
   return (a % b) == 0;
}
Input
> esMúltiplo(30, 2)
> esMúltiplo(100, 3)
Output
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
Código 8 - Operadores && y !
boolean esMayorDeEdad(int edad) {
   return edad >= 18;
}

boolean esAdultoMayor(int edad) {
   return edad >= 60;
}

boolean esAdulto(int edad) {
   return esMayorDeEdad(edad) && !esAdultoMayor(edad);
}
Input
> esAdulto(24)
> esAdulto(81)
Output
true
false
Código 9 - esAñoBisiesto, predicados complejos
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));
}
Input
> esAñoBisiesto(1900)
> esAñoBisiesto(2000)
> esAñoBisiesto(2024) 
Output
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

Código 10 - máximo usando el operador ternario
double max(double a, double b) {
  return (a > b) ? a : b;
}
Input
> max(3.0, 5.0) 
Output
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 tiene un valor equivalente a «1.0» puedes usar:

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-11e-1
1 x 10-21e-2
1 x 1051e-5
6.6743 x 10-116.6743e-11
6.6378 x 1066.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:

Código 11
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:

Código 12
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.

E2.1
int multiplicación(String número1, String número2) {
  return número1 * número2;
}
E2.2
int suma(int número1, int número2) {
  return + número1 número2;
}
E2.3
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;
}
Input
> truncado(123)
> truncado(456)
> truncado(9)
> truncado(0)
Output
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;
}
Input
> últimoDígito(123)
> últimoDígito(456)
> últimoDígito(9)
> últimoDígito(0)
Output
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);
}
Input
> únicoDígito(0)
> únicoDígito(1)
> únicoDígito(5)
> únicoDígito(9)
> únicoDígito(10)
> únicoDígito(88)
Output
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.

Input
> esPar(2)
> esPar(13)
Output
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.

Input
> esImpar(2)
> esImpar(13)
Output
false
true

E2.10

Escriba una función, diferenciaDeCuadrados() que tome dos números enteros y devuelva el resultado de a2 - b2.

Input
> diferenciaDeCuadrados(3,2)
> diferenciaDeCuadrados(1,1)
Output
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.

Input
> tercerÁngulo(60.0, 60.0)
> tercerÁngulo(45.0, 90.0)
> tercerÁngulo(35.0, 50.0)
Output
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».

Input
> validarMúltiploDe7(-7)
> validarMúltiploDe7(0)
> validarMúltiploDe7(91)
> validarMúltiploDe7(9100)
Output
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.

Input
> validar(0, 1, 2)
> validar(1, 1, 2)
> validar(2, 1, 3)
> validar(0, 3, 3)
> validar(1, 3, 5)
Output
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:

Input
> cobro(1)
> cobro(10)
> cobro(15)
> cobro(90)
> cobro(1_000)
Output
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.

Input
> inicio(6, 1)
> inicio(6, 2)
> inicio(6, 3)
> inicio(10, 2)
Output
0
6
12
10
E2.15
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)

Scroll to Top