Professional Documents
Culture Documents
Todos los lenguajes de programación permiten realizar operaciones entre los tipos de
datos básicos: suma, resta, producto, cociente, etc., de dos números
Java tiene cinco operadores aritméticos cuyo significado se muestra en la tabla adjunta:
El cociente entre dos enteros da como resultado un entero. Por ejemplo, al dividir 20
entre 7 nos da como resultado 2.
El operador módulo da como resultado el resto de la división entera. Por ejemplo 20%7
da como resultado 6 que es el resto de la división entre 20 y 7.
El operador módulo también se puede emplear con números reales. Por ejemplo, el
cociente entre 7.5 y 3.0 es 2.5 y el resto es cero, es decir, 7.5=3.0 x 2.5+ 0. El operador
módulo, funciona de la siguiente forma 7.5=3.0 x 2+1.5, calcula la diferencia entre el
dividendo (7.5) y el producto del divisor (3.0) por la parte entera (2) del cociente,
devolviendo 1.5. Así pues, la operación 7.5%3.0 da como resultado 1.5.
El operador asignación =
Nos habremos dado cuenta que el operador más importante y más frecuentemente
usado es el operador asignación =, que hemos empleado para la inicialización de las
variables. Así,
int numero;
numero=20;
La primera sentencia declara una variable entera de tipo int y le da un nombre (numero).
La segunda sentencia usa el operador asignación para inicializar la variable con el
número 20.
a=b;
que asigna a a el valor de b. A la izquierda siempre tendremos una variable tal como a,
que recibe valores, a la derecha otra variable b, o expresión que tiene un valor. Por
tanto, tienen sentido las expresiones
a=1234;
double area=calculaArea(radio);
superficie=ancho*alto;
1234=a;
calculaArea(radio)=area;
Expresión Significado
x+=y x=x+y
x-=y x=x-y
x*=y x=x*y
x/=y x=x/y
Así, la sentencia
x=x+23;
x+=23;
algo = algo;
La variable algo toma el valor de algo; todo queda como antes. Ahora aumentemos el
valor de la variable en 3 unidades.
algo = algo + 3;
Aquí la variable toma el valor que tenía más 3 unidades. Existe una forma de simplificar
la notación anterior. Es la siguiente:
Se juntaron el operador de suma con el de asignación. Este atajo se puede realizar para
otras operaciones además de la suma. Es útil cuando la operación contiene como primer
operando al valor de la misma variable en la que se almacena el resultado.
Operadores de asignación
Operación Operador Utilización Operación equivalente
Suma += A += B A=A+B
Resta -= A -= B A=A-B
Multiplicación *= A *= B A=A*B
División /= A /= B A=A/B
Resto de división %= A %= B A=A%B
Desplazamiento a la izquierda <<= A <<= B A = A << B
Desplazamiento a la derecha >>= A >>= B A = A >> B
Desplazamiento a la derecha sin signo >>>= A >>>= B A = A >>> B
AND de bits &= A &= B A=A&B
OR de bits |= A |= B A=A|B
XOR de bits ^= A ^= B A=A^B
Concatenación de strings
El operador + cuando se utiliza con strings y otros objetos, crea un solo string que
contiene la concatenación de todos sus operandos. Si alguno de los operandos no es
una cadena, se convierte automáticamente en una cadena. Por ejemplo, en la
sentencia anterior el número del tipo double que guarda la variable tC se convierte en
un string que se añade al string "la temperatura centígrada es ".
Como vemos en el listado, para mostrar un resultado de una operación, por ejemplo, la
suma de dos números enteros, escribimos
iSuma=ia+ib;
System.out.println("El resultado de la suma es "+iSuma);
Concatena una cadena de caracteres con un tipo básico de dato, que convierte
automáticamente en un string.
System.out.println("**********************************");
System.out.println("Operaciones con números decimales");
double da=7.5, db=3.0;
double dSuma=da+db;
System.out.println("El resultado de la suma es "+dSuma);
double dProducto=da*db;
System.out.println("El resultado del producto es "+dProducto);
double dCociente=da/db;
System.out.println("El resultado del cociente es "+dCociente);
double dResto=da%db;
System.out.println("El resto de la división es "+dResto);
}
}
La precedencia de operadores
El lector conocerá que los operadores aritméticos tienen distinta precedencia, así la
expresión
a+b*c
es equivalente a
a+(b*c)
ya que el producto y el cociente tienen mayor precedencia que la suma o la resta. Por
tanto, en la segunda expresión el paréntesis no es necesario. Sin embargo, si queremos
que se efectúe antes la suma que la multiplicación tenemos de emplear los paréntesis
(a+b)*c
a/(b*c);
o bien,
a/b/c;
cuya codificación es
tC=(tF-32)*5/9;
tC=((tF-32)*5)/9;
public class PrecedeApp {
public static void main(String[] args) {
int tF=80;
System.out.println("la temperatura Fahrenheit es "+tF);
int tC=(tF-32)*5/9;
System.out.println("la temperatura centígrada es "+tC);
}
}
La conversión automática y promoción (casting)
int a=5;
double b=3.2;
double suma=a+b;
Cuando se declaran dos variables una de tipo int y otra de tipo double.
int entero;
double real=3.20567;
entero=real;
int ia=7;
int ib=3;
double dc=ia/ib;
Si queremos obtener una aproximación decimal del número 7/3, hemos de promocionar
el entero ia a un número en coma flotante, mediante un procedimiento denominado
promoción o casting.
int ia=7;
int ib=3;
double dc=(double)ia/ib;
Como aplicación, consideremos el cálculo del valor medio de dos o más números enteros
int edad1=10;
int edad2=15;
double media=(double)(edad1+edad2)/2;
El valor medio de 10 y 15 es 12.5, sin la promoción se obtendría el valor erróneo 12.
Imaginemos ahora, una función que devuelve un entero int y queremos guardarlo en
una variable de tipo float. Escribiremos
float resultado=(float)retornaInt();
++ Incremento
-- Decremento
Actúan sobre un único operando. Se trata de uno de los aspecto más confusos para el
programador, ya que el resultado de la operación depende de que el operador esté a la
derecha i++ o a la izquierda ++i.
i=i+1; //añadir 1 a i
i++;
i=i-1; //restar 1 a i
i--;
j=i++;
j=i;
i++;
j=++i;
asigna a j el valor incrementado de i. Por ejemplo, si i valía 3, después de ejecutar la
sentencia j e i toman el valor de 4. Lo que es equivalente a las dos sentencias
++i;
j=i;
public class UnarioApp {
public static void main(String[] args) {
int i=8;
int a, b, c;
System.out.println("\tantes\tdurante\tdespués");
i=8; a=i; b=i++; c=i;
System.out.println("i++\t"+a+'\t'+b+'\t'+c);
i=8; a=i; b=i--; c=i;
System.out.println("i--\t"+a+'\t'+b+'\t'+c);
}
}
Operadores relacionales
Operador Utilización Resultado
> A>B verdadero si A es mayor que B
>= A >= B verdadero si A es mayor o igual que B
< A<B verdadero si A es menor que B
<= A <= B verdadero si A es menor o igual que B
== A == B verdadero si A es igual a B
!= A != B verdadero si A es distinto de B
No nos olvidemos de los char, que también participan. Podemos comparar caracteres,
pues internamente están almacenados como números.
char a = 'A';
char b = 'B';
boolean x = a > b;
Entre los booleanos solo se permiten los operadores de equivalencia, es igual (==) o es
distinto (!= )
boolean x = true;
boolean y = x == x;
boolean z = x != y;
Operadores booleanos
Nombre Operador Utilización Resultado
verdadero cuando A y B son verdaderos. Evaluación
AND && A && B
condicional.
verdadero cuando A o B son verdaderos. Evaluación
OR || A || B
condicional.
NOT ! !A verdadero si A es falso.
verdadero cuando A y B son verdaderos. Siempre
AND & A&B
evalúa ambos operandos.
verdadero cuando A o B son verdaderos. Siempre
OR | A|B
evalúa ambos operandos.
XOR ^ A^B verdadero cuando A y B son diferentes
Cada una de estas operaciones tiene asociada una tabla de verdad. Esto nos permite ver
el resultado de un operador aplicado a las distintas combinaciones de valores que
pueden tener los operandos. A continuación mostraremos cómo se comporta el
operador AND mediante su tabla de verdad.
Si probamos a quitar un ampersand ( & ) del operador, vemos que obtenemos los
mismos resultados. Existen dos operadores AND, uno con dos símbolos & y el otro con
uno solo. También tenemos dos operadores OR.
Parece extraño, sobre todo porque tienen la misma tabla de verdad. Pero internamente
tienen un comportamiento diferente.
Cuando estamos en presencia de un operador con un solo símbolo, siempre se evalúan
ambos operandos. En cambio para el operador con el símbolo repetido, su evaluación
cambia según el valor del primer operando. Por ejemplo tenemos la siguiente operación.
El resultado es falso, pero el intérprete tiene que mirar el segundo operando para
saberlo.
Sin ningún tipo de emoción, aburridamente el intérprete nos avisa que el resultado es
"false". Ahora verá. Quitemos un símbolo & y quedémonos con uno solo. El resultado es
otro :
java.lang.ArithmeticException: / by zero
La primera vez verificó que x!=0 era falso, entonces dio por terminada la operación con
el resultado falso. Cuando cambiamos de operador, evaluó los dos operandos y cayó en
nuestra trampa. Tuvo que calcular cuánto es y / x dando luego un error de división por
cero.
Los operadores booleanos son muy amigos de los relacionales. Se llevan bien porque los
últimos dan resultados booleanos. Entre ambos tipos de operadores se pueden construir
instrucciones más complejas.
Por ejemplo, queremos saber si un número está dentro de un rango. Solo tenemos que
compararlo con los extremos:
int y = 4;
boolean x = ( y > 3 ) && ( y < 6 );
Ahora deseamos saber si una variable tiene el valor "a" no importando si es mayúscula
o minúscula.
char c = 'b';
boolean x = ( c == 'a' ) || ( c == 'A' );
No olviden que el operador de equivalencia (==) tiene dos símbolos igual (=), si colocan
uno solo les dará un error de asignación.
Operadores de bits
El método más sencillo de representación son los números naturales. Por ejemplo, si
tengo el número 85 en decimal, solo tengo que llevarlo a binario y obtengo una serie de
unos y ceros:
1010101 = 85 en binario
Cada dígito (un cero o un uno) de este número se llama bit. Java tiene una serie de
operadores capaces de manipular estos dígitos, son los operadores de bits.
Operadores de bits
Para operar a nivel de bit es necesario tomar toda la longitud predefinida para el tipo de
dato. Estamos acostumbrados a desechar los ceros a la izquierda en nuestra
representación de números. Pero aquí es importante. Si trabajamos una variable de tipo
short con un valor de 3, está representada de la siguiente manera:
0000000000000011
int j = 33;
int k = j << 2;
Este es el resultado:
00000000000000000000000000100001 : j = 33
00000000000000000000000010000100 : k = 33 << 2 ; k = 132
Cada "hueco" que queda a la derecha tras correr este número se rellena con ceros. Los
bits a la izquierda se pierden, no es una operación de rotación. Si prestamos atención,
observaremos que esta operación multiplicó a j por 2 tantas veces como posiciones se
ha desplazado. En este caso se multiplicó por 4 ( 2 x 2 ). Hay que notar que el signo del
número puede cambiar tras la operación (por ejemplo 1 << 31 = -2147483648).
Desplazamiento a la derecha con signo
Volvamos a colocar como estaban los bits del caso anterior. Queremos obtener
nuevamente el número 33. Para esto desplazamos el número 132 dos posiciones a la
derecha.
int k = 132;
int m = k >> 2;
00000000000000000000000010000100 : k = 132
00000000000000000000000000100001 : m = 132 >> 2 ; m = 33
Podemos ver que el corrimiento a la derecha realiza una división de enteros. Divide por
2, tantas veces como posiciones desplazadas.
Veamos qué ocurre si pretendemos realizar un desplazamiento a la derecha con un
número negativo. Tengan en cuenta que la representación de números es de
complemento a 2. Si tengo una variable de tipo int con el valor –1, internamente está
almacenada de la siguiente forma :
11111111111111111111111111111111 : -1 complemento a 2
El resultado es: -1
int x = -1;
int y = x >>> 2;
Ahora nos damos cuenta que se han agregado dos ceros a la izquierda. Este operador
desplaza a la derecha, pero no tiene en cuenta el signo. Siempre agrega bit con el valor
cero, por lo que se llama desplazamiento sin signo. Este operador suele ser más
adecuado que el >> cuando queremos manipular los bits mismos, no su representación
numérica.
El resultado da 128
Operador OR de Bits
Si por lo menos uno de los dos bits comparados es 1, establece el resultado en 1. De lo
contrario da como resultado 0.
El resultado da 148
El resultado da 20
El resultado da -133
Como los enteros negativos en Java se representan con el método del complemento a
dos, podemos realizar un sencillo experimento de cambiarle el signo a un número. Para
realizarlo debemos aplicar a un entero el operador NOT y sumarle uno.
int x = 123;
int y = ~x;
int z = y + 1;
El resultado da -123,
PRECEDENCIA
Civilizadamente se organizan de acuerdo al nivel de precedencia de cada uno.
Primeramente proceden los unarios, luego los aritméticos, después los de bits,
posteriormente los relacionales, detrás vienen los booleanos y por último el operador
de asignación. La regla de precedencia establece que los operadores de mayor nivel se
ejecuten primero.
Precedencia de operadores
Descripción Operadores
suma y resta +-
equivalencia == !=
operador XOR ^
operador OR |
OR booleano ||
condicional ?:
operadores de asignación = += -= *= /= %= &= ^= |= <<= >>= >>>=
int j = 1 + 3 * 4; // resultado j = 13
Desde que aprendimos aritmética básica, conocemos la regla que nos obliga a calcular
la multiplicación antes de una suma. Esto también se cumple en Java.
int j = 1 + 3 – 4; resultado j= 0;
Utilización de paréntesis
Se utilizan para aislar una porción de la expresión de forma que el cálculo se ejecute de
forma independiente. Puede forzar a una expresión a ignorar las reglas de precedencia.
int j = 1 + 3 * 4; // resultado j = 13
int h = (1 + 3) * 4 // resultado h = 16
int k = 1 + (h = 3);