"i Socorro!" dice el programador novato, "necesito saber si el bit número 3
de un entero está puesto a 1. ¿Hay alguna forma fácil de hacerlo?" "Claro", le dice, "puede usar un operador a nivel de bit".
Los operadores a nivel de bit permiten examinar cada uno de los bits de los valores. Por ejemplo, cuando se usa el operador a nivel de bit & con dos
operandos, se realiza la operación lógica AND con cada bit de un operando y su correspondiente en el otro. Si ambos bits son 1, un uno aparece en ese lugar en el resultado; de lo contrario, será un cero. Por ejemplo, se puede hacer la prueba del programador novato de si el tercer bit de un valor está a 1 haciendo el AND lógico con un número para el que se sabe que el tercer bit es l. Si el resultado de la operación AND no es cero, el tercer bit del valor original era 1. Aquí se muestra cómo sería el código:
public class app
I
public static void main(String[] args)
{
int value = 12;
int bit3setting = value & 1 << 3;
if (bit3setting ! = 0 ) {
System.out.println("Bit 3 está activo.");
1
else {
System.out.println("Bit 3 no está activo.");
}
1
1
Este es el resultado:
C:\>java app Bit 3 está activo.
Los operadores a nivel de bit se pueden encontrar en la tabla 3.2. En pocas palabras, así es cómo funcionan: El operador OR (1) devuelve O cuando ambos bits son O y devuelve 1 en caso contrario. El operador AND (&)
devuelve 1 cuando ambos bits son 1 y devuelve O en caso contrario. Final- mente, el operador Xor (", llamado OR exclusivo) devuelve 1 cuando un bit es O y el otro es 1 y devuelve O en caso contrario.
Cuando los operadores &,
"
yI
operan con valores booleanos verdadero1 falso, se consideran operadores lógicos a nivel de bit. Los operadores lógicos a nivel de bit funcionan igual que los operadores a nivel de bit (sustituyen falso por O y verdadero por l), como se puede ver en la tabla 3.3.En pocas palabras, así funcionan los operadores lógicos a nivel de bit: el operador OR (1) devuelve falso cuando ambos operandos son falsos y devuel- ve verdadero en caso contrario. El operador AND (&) devuelve verdadero cuando ambos operandos son verdaderos y devuelve falso en caso contrario. El operador Xor (") devuelve verdadero cuando un operando es falso y uno es verdadero, y devuelve falso en caso contrario.
Tabla 3.2. Los operadores a nivel de bit.
Tabla 3.3. Los operadores lógicos a nivel de bit.
Falso Falso Falso Falso Falso
Verdadero Falso Verdadero Falso Verdadero
Falso Verdadero Verdadero Falso Verdadero
Verdadero Verdadero Verdadero Verdadero falso
Este es un ejemplo en el que se han puesto dos condiciones lógicas juntas, visualizando un mensaje en el caso de que cualquiera de ellas sea verdad, usando el operador 1:
public class app
I
public static void main(String[] args)
I
int budget = 1;
boolean fired = falce;
if (budget < O 1 fired == t ~ e ) i Syctem.out.println("Uh oh. ' O ) ; 1 elce { Syctem.out.println("~odavía es solvente.") ; 1
>
1 Este es el resultado: C:\>java app ~odavía es solvente.En el siguiente ejemplo, insisto en que la temperatura está entre 60 y 90
grados, usando el operador lógico a nivel de bit &, antes de visualizar un mensaje:
public class app
{
public static void main(String[l args)
I
int temperature = 70;
if (tanperature < 90 & temperature > 60) {
System.out.println("Podemos ir de merienda.") ; 1
>
1 Este es el resultado: C:\>java app podemos ir de meriendaComo se puede ver, los operadores lógicos a nivel de bit pueden ser muy útiles. Java además incluye dos operadores lógicos: && y II. Veámoslos a continuación.
&& y II lógicos
Los dos operadores lógicos que generalmente se usan en expresiones son
AND (&&) y OR (11). La tabla 3.4 muestra cómo funcionan estos operadores.
El operador OR (11) devuelve falso cuando ambos operandos son falsos y devuelve verdadero en caso contrario. El operador AND (&&) devuelve verdadero cuando ambos operandos son verdaderos y devuelve falso en caso contrario. Estos operadores se usan para enlazar cláusulas lógicas, se usa AND cuando se quiere que ambas cláusulas sean verdad y OR cuando sólo se necesita que una de las dos sea verdadera.
Este es un ejemplo del punto anterior, en el que se usa &&:
public class app
{
public static void main(String[l args)
{
int temperature = 70;
if (temperature < 90 && temperature > 6 0 ) I
System.out.println("Podemos ir de merienda."); 1 1 1 El resultado es: C:\>java app Podemos ir de merienda.
Los operadores && y II tienen además otra propiedad interesante: son operadores cortocircuito, lo que quiere decir que si pueden determinar todo lo que necesitan saber evaluando el operando de la izquierda, no evaluarán el operando derecho. Esto es muy útil en casos como el que sigue, en el que estamos comprobando si un valor tiene O y si u inverso es menor que 1000. Si el valor es O, la segunda parte de la expresión, en la que se calcula su inverso, no se ejecuta. De esta forma, se evita un error de desbordamiento al intentar dividir entre cero.
Tabla 3.4. Los operadores lógicos.
1
Falso Falso Falso FalsoI
1
Verdadero Falso Verdadero FalsoI
1
Falso Verdadero Verdadero FalsoI
1
Verdadero Verdadero Verdadero VerdaderoEste es el código:
public class app
I
public static void main(String[] args)
{
double value = 0;
if (value I = O && 1 / value < 1000) {
System.out.println("E1 valor no es demasiado pequeño.");
1
else (
System.out.println("E1 valor es demasiado pequeño.");
1
1
1
Este es el resultado:
C:\>java app
~l valor es demasiado pequeso
Los operadores lógicos se diferencian de los operadores lógicos a nivel de bit en que los primeros son operadores cortocircuito. Para ver cómo funcio- nan, echemos un vistazo al código siguiente, en el que la asignación de la sentencia $se ejecuta cuando se usa el operador & pero no cuando se usa el operador cortocircuito &&:
public class app {
public static void mainíString[] args)
I
double intl = 0, int2 = 1 , int3 = 1;
if ( i n t l i = O & ( i n t 2 = 2 ) == 1 ) { 1 System.out.println("int2 = " + int2); if ( i n t l != O & ( i n t 3 = 2 ) == 1 ) { 1 System.out.println("int3 = " + int3); 1 1 Este es el resultado: C:\>java app int2 = 2 .O int3 = 1.0
El operador If-Then-Else: ?:
"De acuerdo", dice el programador novato (PN), "soy un experto en opera- dores. Estoy preparado para las sentencias condicionales de Java". "No tan rápido", le dice. "¿Qué hay sobre el operador condicional ternario?" "¿El qué?" pregunta PN.
Hay un operador Java que funciona como una sentencia if-else, el opera-
dor ternario (?:). Este operador se llama operador ternario porque involucra tres operandos, una condición y dos valores:
valor = condición ? valorl : valora:
Si la condición es verdadera, el operador ?: devuelve valorl y, en caso contrario devuelve valor2. De esta forma, la sentencia precedente funciona como la siguiente sentencia
if:
if (condición) I value = valorl; } else { value = valora; 1
Veamos un ejemplo en el que un entero entre O y 15 se convierte a hexadecimal usando el operador ?:. Este operador es perfecto para esto, porque se puede usar para devolver una cadena construida a partir de un valor, si el valor es menor que 10 o un dígito si el valor es mayor o igual que 10, como sigue:
public class app
(
public static void main(String[l args)
I
int value = 15;
String digit, chars[] = ( "a ", " b " , " c " , " d " , "e ", " f " } ;
Digit = valuo < 10 ? String valueOf(va1ue) : charstvalue - 101; System.out.println(value + ' = Ox" + digit);
} }
Este es el resultado:
C:\>java app 15 = Oxf
Operadores de asignación: = y [operador]=
La mayor parte de los operadores básicos son operadores de asignación (ya hemos usado estos operadores en el libro). El operador = se puede utilizar para asignar a una variable un valor literal o el valor de otra variable, como sigue:
public class app
I
public static void main(String[l args)
{
int value = 12;
System.out.println("E1 valor = " + value);
1
1
Este es el resultado:
C:\>java app El valor = 12
Como en C++, se pueden ejecutar múltiples asignaciones en la misma sentencia (esto funciona porque el operador asignación, devuelve el valor asignado):
public class app
(
public static void main(String[l args)
(
Este es el resultado:
Además, como en C++, se pueden combinar muchos operadores con el operador de asignación (=). Por ejemplo, += es el operador de asignación de la suma, que significa que value
+=
2 es una forma corta d e value = value+
2.Esto es un ejemplo que utiliza el operador de asignación de la multiplicación: public class app
I
public static void main(String[l args)
{ int value = 10: value *= 2; System.out.println("va1ue * 2 = " + v a l u e ) ; 1 1 Este es el resultado: C: \>java app value * 2 = 20
Hay bastantes combinaciones d e operadores de asignación. Esta es la lista:
%= (asignación de módulo)
&= (asignación a nivel de bit de AND)
*= (asignación de multiplicación)
/= (asignación de división)
"= (asignación a nivel de bit de Xor)
I= (asignación a nivel de bit de OR)
+=
(asignación de suma)<= (menor o igual que)
-= (asignación de resta)
>>=
(asignación de desplazamiento a la derecha)>>>=
(asignación de desplazamiento a la derecha con relleno de ceros) Esto completa la lista de los operadores de Java, pero hay una forma más popular de gestionar matemáticas en Java, la clase Math. Esta clase es parte del paquete java.lang (que el compilador Java importa por defecto). Echare- mos un vistazo a esta clase en la siguiente sección.Utilización de la clase Math
"Oye", dice el programador novato (PN)",quiero elevar3 a la potencia 4, pero no hay ningún operador de Java para la potenciación". "Se puede usar el
método pow de la clase Math", le dice. "Y de esta forma, 3 elevado a la
potencia 4 es 81". "La crearé cuando Java me lo pida, " dice PN.
Se puede usar la clase java.lang.Math para ejecutar muchas operaciones matemáticas. Por ejemplo, así se resuelve el problema del programador nova- to usando el método Math.pow:
public class app
I
public static void main(String[l args)
I Syritem.out.println(.3 x 3 x 3 x 3 = " + ~ath.por(3, 4 ) ) s 1 1 Este es el resultado: C:\>java app 3 x 3 ~ 3 = 8 1 . 0 ~ 3
Las constantes y métodos de la clase son:
double E: El número 'e' (2.7 1828 18284590452354) double PI: La constante pi (3.14159265358979323846) double sin(doub1e a): Seno
double tan(doub1e a): Tangente double asin(doub1e a): Arcoseno double acos(doub1e a): Arcocoseno double atan(doub1e a): Arcotangente
double atan2(double a): Arcotangente (versión 2 del operando) double exp(doub1e a): Eleva el número 'e' a la potencia 'a' double log(doub1e a): Logaritmo del valor 'a'
double sqrt(doub1e a): Raíz cuadrada del valor 'a'
double pow(doub1e a, double b): Elevar el valor 'a' a la potencia 'b' double cell(doub1e a): Método ceilling
double floor(doub1e a): Métodofloor double rint(doub1e a): Entero aleatorio int round(doub1e a): Redondea un double long round(float a): Redondea unfloat double random( ): Número aleatorio int abs(int a): Valor absoluto de un entero long abs(1ong a): Valor absoluto de un long float abs(float a): Valor absoluto de unfloat
double abs(doub1e a): Valor absoluto de un double int min(int a, int b): Mínimo de los dos enteros long min(1ong a, long b): Mínimo de dos long float min(float a,float b): Mínimo de dosfloat
double min(doub1e a, double b): Mínimo de dos double int max(int a, int b): Máximo de dos enteros
long max(1ong a, long b): Máximo de dos long float max(float a,float b): Máximo de dosfloat