Tipos primitivos en Java II – decimales, char y boolean

Este artículo es la continuación del anterior, donde te hablé sobre los tipos primitivos en Java que se utilizan para guardar un valor numérico entero. En el artículo de hoy te voy a hablar sobre el resto de tipos primitivos: float, double, char y boolean.

More...

Tipos primitivos en Java: números decimales

Los tipos primitivos en Java que se encargan de "guardar" números decimales son float y double.

¿Recuerdas las "cajas" de las que te hablé en el artículo anterior? Pues bien, las "cajas" en las que guardamos números decimales son bastante grandes. Como puedes ver en la tabla que te incluí en el último artículo, un float tiene un tamaño de 32 bits, mientras que un double tiene... el doble: 64 bits. Como te puedes imaginar, el tamaño de un número float o double puede llegar a alcanzar valores muy elevados.

Todos los números decimales son de tipo double

¿Recuerdas cuando te dije, en el artículo anterior, que todos los números enteros eran int?

Este código no compila, porque aunque el rango de long es mayor de la cifra indicada, el rango de int no lo es, y todos los números enteros son int. Pues bien, algo similar ocurre con double: todos los números decimales son double.

La diferencia es que, si bien puedes asignar un número entero tanto a una variable de tipo byte o short sin problema (siempre y cuando no superes el tamaño de la caja byte o short), como a una de tipo long (siempre y cuando no superes el tamaño de int, ya que la cajita long es mayor), no puedes asignar un número decimal a una variable de tipo float sin marcarlo antes con una f (mayúscula o minúscula):

Tipos incompatibles, dice. Para tirarse de los pelos.

También puedes marcar con una d un número decimal (double), y compila y se ejecuta sin problema:

Sufijos en los tipos primitivos en Java

  • Existen tres sufijos para tipos primitivos en Java: L, F y D (y sus respectivas minúsculas).
  • Utiliza L (o su minúscula) cuando asignes un número entero muy grande a una variable de tipo long, ya que si ese número supera el tamaño de int, no va a compilar. No funciona si pretendes asignar a dicha variable un número decimal; no te va a "convertir" el número decimal a entero de tipo long.
  • Utiliza F (o su minúscula) cuando asignes cualquier número decimal o un número entero que supere el tamaño de int a una variable de tipo float
  • Utiliza D (o su minúscula) cuando asignes un número entero que supere el tamaño de int a una variable de tipo double. En este caso, también puedes simplemente añadirle al número un punto y un cero (.0) para convertirlo en un decimal. 
  • Los sufijos D y F (y sus minúsculas) solo se pueden utilizar con números en base diez (no en binario, por ejemplo).

float y double en octal, binario y hexadecimal

Como puedes observar, float no reconoce un número octal, de manera que si utilizas el sufijo f el cero inicial es omitido e imprime 10. En cambio, si no le colocas la f (o si utilizas el sufijo L) el número asignado, 010, es un entero, y como tal puedes expresarlo en base octal. Una vez asignado a una variable float, se transforma en un decimal. Así, obtienes 8.0, el equivalente en base diez del octal 010.

En cuanto a los hexadecimales, la f deja de ser un sufijo para ser un número hexadecimal: ff = 255.

Si pretendes guardar un binario, no puedes utilizar ni el sufijo D ni el F.

Otras maneras de expresar un double o float

Existe una notación, más científica, de expresar un número entero utilizando decimales. Se trata de multiplicar un número por una potencia de 10:

Notación científica en un double

Es decir, 43. Dado que en código no puedes introducir números en superíndice, Java admite que introduzcas una e para expresar cantidades de esta manera:

char, o todos los caracteres Unicode

La cajita del tipo primitivo char puede contener un carácter Unicode, y solo uno. Prueba a ejecutar el siguiente código:

Vayamos por partes, porque está claro que esto requiere una explicación detallada.

Como ves, a la hora de imprimir, todas las líneas (excepto la última) imprimen la letra rusa Я. Esto quiere decir que todos los valores asignados son, en realidad, el mismo.

Vamos a echarle un vistazo a la tabla de caracteres Unicode para comprenderlo:

Ejemplo de carácter Unicode (tipos primitivos en Java)

Cada carácter Unicode tiene asociado un valor numérico. En este caso, la letra Я tiene asociado el número (en base decimal) 1071, que en hexadecimal es 042F. Como recuerdas del último artículo, los tipos primitivos en Java también admiten números en base 2 (binarios), en base 8 (octal) y en base 16 (hexadecimales), utilizando los prefijos respectivos. 1071 es 10000101111 en binario y 2057 en octal.

Ahora bien, ¿qué es el carácter6? En ese caso, he utilizado una notación reservada para el tipo char:

Ejemplo de carácter Unicode en Java

Entrecomillado simple (como cuando introduces un carácter), seguido de la barra invertida ("\"), una u minúscula (de Unicode. Pero no te va a compilar si utilizas una U mayúscula) y el valor hexadecimal del carácter.

Números vs. caracteres en char

Observa el siguiente ejemplo:

¿Qué crees que va a imprimir? (Fijate que uno de los casos coincide con uno de los casos del código anterior).

La respuesta está aquí

¿Qué ha pasado? ¿Por qué la suma no es 8?

En primer lugar, cuando imprimes una variable char, aparece el carácter Unicode que contiene, y nunca el número que se corresponde con ese carácter. De ahí que, en el primer caso, nos encontremos con el carácter asociado al número 4 ('\u0004'): 

En segundo lugar, no confundas un carácter numérico con su valor numérico. El carácter siempre va entrecomillado. Es decir, en el segundo caso se le asigna a la variable char un carácter (porque está entrecomillado). En este caso, no sabemos cuál es el número asociado al carácter 4. Si lo consultas en la tabla Unicode, verás que es el número 52 ('\u0034').

En tercer lugar, cuando realizas una operación matemática con números enteros, sea cual sea su tipo, Java los convierte a int en primer lugar. Es decir, Java ha tomado los valores numéricos de ambos caracteres, 4 y 52 los ha sumado y te ha mostrado el resultado en forma de int: 56.

Valores que admite una variable de tipo char

  • check
    Un número entero positivo, que no supere la cifra de 65535. Este es (casi; a continuación hablaré de boolean) el único tipo primitivo en Java que no admite valores negativos. ¿Recuerdas que en el anterior artículo calculé el tamaño de una variable primitiva a partir del rango en bits? En este caso, no necesitas dividir el valor entre dos para calcularlo.
  • check
    En relación con el anterior, tampoco puedes utilizar números en binario, octal o hexadecimal que superen la cifra de 65535 en sus respectivas bases. Por ejemplo, el valor hexadecimal más elevado que puedes utilizar es 0xffff.
  • check
    Cualquier código Unicode, que consiste de una barra invertida, una u minúscula y un número hexadecimal de cuatro cifras (de nuevo, la cifra más elevada es '\uffff', como el valor hexadecimal pelado), todo entre comillas simples.
  • check
    Cualquier carácter (número, letra, o símbolo), entre comillas simples. Recuerda que sólo puede aparecer UN carácter. Que en el examen no pretendan engañarte colocando entre comillas un número de más de una cifra, que no compila (son muy capaces). 

Cuidado con no confundir char a = 4 y char b = '4'; char d = 44 y char c = '44'. Que no te confundan en el examen de #OCAJ8P

Compártelo

boolean, o verdadero o falso

Las variables de tipo boolean solo admiten uno de los siguientes valores: true o false. Sin comillas, y en minúscula. No se les puede asignar otro valor, ya sea numérico o alfabético.

Las variables de tipo boolean no tienen más misterio.

Conclusión

¡Qué barbaridad! Me he enrollado bien en este artículo, y me he dejado varias cosas en el tintero, de las que hablaré próximamente. Por ahora no te recomiendo ejercicios concretos; crea tus propias clases, utiliza variables primitivas y pásatelo bien programando. ¡Nos vemos la semana que viene!

Si tienes alguna duda o pregunta, que sepas que para eso está la caja de comentarios. ¡Estoy esperando! 🙂

Deja una respuesta 1 comentario