13 de septiembre de 2018

Operadores - Numéricos

Ya hemos visto el operador de asignación. Es uno de los 38 que contiene la especificación de Java 8. En esta entrada veremos los operadores numéricos. Estos operadores junto con otras expresiones, nos van a permitir realizar cálculos, que os recuerdo son una de las partes más generales en las que dividiamos cualquier programa cuando aprendimos qué era programar. En el libro que estamos siguiendo da muchos ejemplos de redondeos y diferencias entre distintos tipos numéricos como int, float o double.

Ahora mismo no voy a entrar en esa profundidad pues en general no influyen demasiado. Al final de esta entrada sí que voy a llamaros la atención en aspectos a tener en cuenta por experiencia personal. Por ahora vamos a ver cuales son los operadores numéricos y unos ejemplos.

Los operadores numéricos permiten hacer cálculos aritméticos. Existen diferencias usándolos con operandos enteros o decimales


Según la especificación de Java los operadores numéricos son (para enteros y decimales):
  1. Suma: +
  2. Resta/Cambio de signo: -
  3. Multiplicación: * (asterisco)
  4. División: /
  5. Módulo (resto): %
  6. Incremento: ++
  7. Decremento: --
Para enteros hay otros a nivel bit que es más raro su uso y no los veremos en esta entrada.

Los 5 primeros se usan con dos operandos. Cuando un operador utiliza dos operandos se conoce como operador binario.

Los operadores 6 y 7 se usan un sólo operando, son unarios (sólo necesitan un operando para incrementar o decrementar) y cambia su comportamiento si lo usamos antes o después de la variable como se ve en el vídeo.

El operador "-" también puede usarse como unario (para cambiar el signo)

El operador "+" podemos usarlo con una cadena de texto para que nos concatene todo en una sola cadena.


Este es un ejemplo para cada uno:
int operando1 = 2;
int operando2 = 3;
int resultado;
System.out.print("Sumo los operandos = ");
resultado = operando1 + operando2;
System.out.println(resultado);
System.out.print("Resto los operandos = ");
resultado = operando1 - operando2;
System.out.println(resultado);
System.out.print("Niego el operando1 = ");
resultado = -operando1;
System.out.println(resultado);
System.out.print("Multiplico los operandos = ");
resultado = operando1 * operando2;
System.out.println(resultado);
System.out.print("Divido los operandos = ");
resultado = operando1 / operando2; // Cociente
System.out.println(resultado);
System.out.print("Resto de dividir los operandos = ");
resultado = operando1 % operando2; // Resto
System.out.println(resultado);
// Comprobamos que los operandos no han cambiado hasta ahora
System.out.println("Imprimo los operandos: op1 = "
        + operando1 + " y op2 = " + operando2);
System.out.print("Incremento el operando1 = ");
System.out.println(++operando1); // Cambio antes de devolver el valor
System.out.print("Decremento el operando1 = ");
System.out.println(operando1--); // Cambio despues de devolver el valor
System.out.print("Imprimo el operando1 = ");
System.out.println(operando1); // Ahora vemos el cambio
Su salida por consola es:

Sumo los operandos = 5
Resto los operandos = -1
Niego el operando1 = -2
Multiplico los operandos = 6
Divido los operandos = 0
Resto de dividir los operandos = 2
Imprimo los operandos: op1 = 2 y op2 = 3
Incremento el operando1 = 3
Decremento el operando1 = 3
Imprimo el operando1 = 2 

Si bien podría haber puesto los ejemplos con números directamente, quiero que desde el principio os acostumbréis a usar variables.

Este uso de los operadores se llama expresión. Una expresión es un fragmento de código que devuelve un valor. El concepto de sentencia que explicamos anteriormente suele usar varias expresiones. El mejor ejemplo son las líneas 23 y 24. Las dos líneas contienen una única sentencia que va obteniendo los sucesivos resultados de concatenar el texto dos a dos hasta que tiene una única cadena de texto que imprime por pantalla.

Es interesante ver cómo las variables no cambian sus valores usando los primeros operadores. Esto es porque no les asignamos nuevo valor. El valor sólo se asigna a la variable "resultado". Sin embargo con el incrementador y decrementador sí que cambia el propio valor de su único operador, pero lo hace antes de devolver el nuevo valor si los usamos a la izquierda de la variable y después si usamos el operador a la derecha.

Las expresiones devuelven un valor, pero no implican un cambio del valor en sus variables.


Conclusiones a tener en cuenta

Como prometí al principio, aquí os dejo mis conclusiones al respecto:
  1. Redondeo de enteros: Esto si es normal encontrarlo. Si hago una división de enteros me redondeará a un entero y puedo tener grandes errores inesperados (sobre todo si es por debajo de 1). Por esto cuando tengamos que realizar operaciones con decimales usaremos float (que ocupa menos memoria) o double (si queremos tener una gran precisión).
  2. Respetar los datos que tenemos: Si leemos un dato externo que tiene el tamaño double y lo convertimos a float vamos a perder precisión. Si ese dato tiene esa precisión debemos valorar el por qué, si lo obviamos puede que confrontando datos con otros procesos haya discrepancias (imaginad una aplicación que sume millones de cantidades decimales distintas). Solo reduciremos el tamaño del dato cuando el error es asumible y no influye en el resultado final.
  3. Comparar decimales del mismo tipo: Lo mejor es comparar los datos del mismo tipo, en caso contrario uno de los dos se "convertirá" al otro tipo produciendo un pequeño error de ajuste. Esto producirá probablemente que una simple comparación de igualdad falle aunque asignemos "el mismo valor". Puedes ver la demostración en la siguiente entrada de operadores de comparación.
  4. Indicar los valores decimales float poniendo una "f" al final (ej: 5.3f), si no lo tomará como un double y nos saldrá un error.
  5. Existen unas clases que encapsulan los valores numéricos primitivos. Si no nos hace falta un valor como objeto (por ejemplo Collection nos obliga a tipos por referencia) se sacará más rendimiento usando tipos primitivos. Este punto puede no entenderse, pero quedará claro cuando veamos Clases, Objetos y Colecciones.

Si tenéis vosotros algún consejo más, os pido que lo dejéis en los comentarios.

No hay comentarios:

Publicar un comentario

Compárteme

Entradas populares