Codemaker Computación por dentro

Computación por dentro Tema 2

Bits y bytes

Dentro del ordenador solo hay interruptores: cada uno está apagado o encendido. Con eso, y solo con eso, se guardan los números, los textos, las fotos y tus programas.

El bit y el byte#

Un bit es uno de esos interruptores: vale 0 (apagado) o 1 (encendido). Un bit solo no dice mucho, así que se agrupan de 8 en 8: 8 bits son un byte.

Ocho casillas, cada una un bit encendido o apagado: 01000001. Ocho bits forman un byte

UnidadCuánto esMás o menos…
Bit0 o 1Un interruptor
Byte8 bitsUna letra
Kilobyte (KB)1.000 bytesUna página de texto
Megabyte (MB)1.000 KBUna foto del móvil, unos pocos MB
Gigabyte (GB)1.000 MBUna película, unos pocos GB
Terabyte (TB)1.000 GBUn disco duro

Contar en binario#

Contamos en decimal porque tenemos diez dedos: cada cifra va del 0 al 9. El ordenador cuenta en binario: cada cifra es un bit, 0 o 1.

El truco para leer un número binario: cada casilla vale el doble que la de su derecha (1, 2, 4, 8, 16…). Se suman las casillas que están a 1:

Las casillas valen 128, 64, 32, 16, 8, 4, 2 y 1. 00000111 es 4 más 2 más 1, 7; 01000001 es 64 más 1, 65

Con un byte, el número más grande es 11111111: 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255. Por eso tantas cosas en informática van de 0 a 255.

Para pasar un número decimal a binario, ve restando las casillas de mayor a menor: 13 = 8 + 4 + 1, así que es 00001101.

El hexadecimal#

Escribir unos y ceros es largo y fácil de equivocarse. El hexadecimal lo resume: cada cifra hexadecimal son 4 bits, y va del 0 al 15. Como no hay cifras para el 10 o el 15, se usan letras:

DecimalHexadecimalBinario
000000
110001
………
991001
10A1010
11B1011
12C1100
13D1101
14E1110
15F1111

Así, dos cifras hexadecimales son justo un byte: FF = 11111111 = 255.

Ya lo has visto en los colores: #007AFB son tres bytes, cuánto rojo, cuánto verde y cuánto azul:

El color #007AFB se lee por parejas: 00 de rojo, 7A (122) de verde y FB (251) de azul

En Java#

Java te deja escribir números en binario (con 0b delante) y en hexadecimal (con 0x), y pasarlos a texto:

Java
System.out.println(0b111);                       // binario
System.out.println(0xFF);                        // hexadecimal
System.out.println(Integer.toBinaryString(65));
System.out.println(Integer.toHexString(255));
Salida
7
255
1000001
ff

Cada tipo, su tamaño#

Cada tipo de Java ocupa siempre los mismos bytes, tenga el número que tenga. Un int con un 7 ocupa lo mismo que uno con 2.000.000:

Cuánto ocupa cada tipo: byte 1 byte, char 2, int 4, long 8 y double 8

TipoOcupaGuarda
byte1 byteNúmeros de −128 a 127
char2 bytesUn carácter
int4 bytesNúmeros de unos −2.000 millones a 2.000 millones
long8 bytesNúmeros enormes, hasta 9 trillones
double8 bytesNúmeros con decimales
booleanJava no lo fijatrue o false: bastaría un bit, pero ningún ordenador guarda un bit suelto

Cuando el número no cabe: el desbordamiento#

¿Qué pasa si al int más grande le sumas 1? No cabe, y da la vuelta, como un cuentakilómetros:

Como un cuentakilómetros que pasa de 9999 a 0000, un int que pasa de su máximo, 2.147.483.647, da la vuelta a −2.147.483.648

Java
int maximo = Integer.MAX_VALUE;
System.out.println(maximo);
System.out.println(maximo + 1);
Salida
2147483647
-2147483648

Java no avisa: el programa sigue con un número negativo que no tiene sentido. Si tus números pueden ser muy grandes, usa long.

Los decimales no son exactos#

Un double guarda los decimales en binario, y hay números que en binario no se pueden escribir exactos, igual que 1/3 en decimal es 0,3333… sin fin. Por eso:

Java
System.out.println(0.1 + 0.2);
Salida
0.30000000000000004

Atención

No compares dos double con ==: puede salir false aunque «deberían» ser iguales. Y no uses double para dinero si necesitas los céntimos exactos.

Los textos también son números#

Una letra es un número con una tabla que dice qué letra es cada número. En la tabla básica, ASCII, la A es el 65, la B el 66… Por eso en Java un char se puede usar como número:

Java
char letra = 'A';
System.out.println((int) letra);
System.out.println((char) (letra + 1));
Salida
65
B

ASCII solo tiene letras inglesas. Para la ñ, las tildes, los emojis o el chino está Unicode, y la forma más usada de guardarlo en un fichero es UTF-8: las letras inglesas ocupan 1 byte, y la á o la ñ, 2.

Si un programa guarda un texto en UTF-8 y otro lo lee pensando que es otra tabla, cada byte se lee como una letra distinta: á sale como á. Ese es el famoso error de las tildes rotas.

Errores frecuentes#

Lo que pasaPor quéSolución
Un número sale negativo sin motivoDesbordamiento: el resultado no cabía en un intUsa long
0.1 + 0.2 == 0.3 da falseLos double no son exactosCompara si la diferencia es muy pequeña: Math.abs(a - b) < 0.0001
Las tildes salen como áEl fichero se escribió con una codificación y se lee con otraUsa UTF-8 al escribir y al leer
Un disco de 1 TB sale como 931 GBEl fabricante cuenta 1 TB = 1.000.000.000.000 bytes, y Windows divide entre 1.024 en vez de entre 1.000No falta nada: son dos formas de contar