Estamos acostumbrados a que los ordenadores manejen cualquier tipo de información: números, textos, gráficos, sonidos, fórmulas... Sin embargo, en realidad, los ordenadores sólo pueden manejar números, y más concretamente, sólo ceros y unos.
De hecho, si profundizamos más, incluso esto es una convención, y en lo más profundo, lo único que encontraremos en un ordenador son células básicas que pueden contener y manipular dos estados. A uno de esos estados se le asigna valor lógico cero, y al otro un uno.
Los técnicos electrónicos llaman a cada uno de estas células biestable, precisamente, porque pueden tener dos estados. A cada uno de esos estados se le llama bit. Un bit es la unidad mínima de información.
Desde los primeros ordenadores, acceder a bits como unidad ya resultaba poco práctico, así que los bits se agruparon formando unidades mayores.
En la práctica, nosotros hacemos lo mismo con los números, para manejar números mayores de nueve usamos dos dígitos, de modo que cada uno de ellos tiene un valor diferente según la posición que ocupe. Por ejemplo, en el número 23, el 2 tiene un peso 10 veces mayor que el 3, ya que ocupa una posición más a la izquierda. Si usamos tres dígitos, el tercero por la derecha tiene un peso 100 veces mayor que el primero, y así suscesivamente.
Los primeros ordenadores usaban unidades de cuatro bits, nibbles. El motivo era, sencillamente, simplificar el acceso a la información por parte de los humanos. Para almacenar un dígito en base 10, que son los que usamos nosotros, se necesitan al menos cuatro dígitos binarios.
Veamos esto. Análogamente a lo que pasa con nuestros números en base 10, cada posición contando desde la derecha será dos veces mayor que la anterior. El primer dígito, desde la derecha, tiene peso 1, el segundo 2, el tercero 4, el cuarto 8, etc.
Estas relaciones de peso son potencias de la base de numeración elegida. En base 10 son potencias de 10: 100 (=1), 101 (=10), 102 (=100), 103 (=1000), 104 (=10000), etc. En base 2 son potencias de dos: 20 (=1), 21 (=2), 22 (=4), 23 (=8), 24 (=16), etc.
Así, con tres bits tenemos que el número mayor que podemos codificar es "111", es decir:
1*22+1*21+1*20 = = 1*4+1*2+1*1 = 4+2+1 = 7
Esto es insuficiente para codificar números entre 0 y 9, nos faltan dos valores, por lo tanto, necesitamos otro bit. Con cuatro podemos llegar hasta:
1*23+1*22+1*21+1*20 = = 1*8+1*4+1*2+1*1 = 8+4+2+1 = 15
Con esto, en realidad, nos sobran seis valores, pero podemos ignorarlos (de momento).
Esta forma de codificación se denomina BCD, es decir, Decimal Codificado en Binario. La tabla de valores BCD es la siguiente:
Código binario | Dígito decimal |
---|---|
0000 | 0 |
0001 | 1 |
0010 | 2 |
0011 | 3 |
0100 | 4 |
0101 | 5 |
0110 | 6 |
0111 | 7 |
1000 | 8 |
1001 | 9 |
Durante un tiempo, los ordenadores trabajaban con palabras de cuatro bits, siempre se ha llamado palabras a las agrupaciones de bits, y según la tecnología ha ido avanzando, las palabras han ido teniendo más bits.
Para simplificar y sobre todo, para conseguir mejores resultados, el acceso a la memoria también se hace mediante palabras. El procesador no accede a bits de memoria, sino a palabras, y la memoria se organiza por palabras. A cada una de esas palabras se le asigna una dirección: una dirección de memoria.
De modo que en un procesador de cuatro bits, cada dirección de memoria contiene un nibble, y en cada nibble se pueden almacenar un dígito decimal en la forma de dígitos BCD o una instrucción del proceador.
Entre los avances más destacados de los procesadores están el de usar la misma memoria para almacenar los datos y los programas. El procesador puede leer una instrucción de programa desde la memoria, ejecutarla, pasar a la siguiente instrucción, y repetir el proceso.
Siguiendo la misma idea, se puede acceder a varias direcciones contiguas de memoria para almacenar números mayores o instrucciones más complejas (16 instrucciones son pocas incluso para un ordenador primitivo), con dos nibbles tenemos posibilidad de almancenar 256 instrucciones.
Las palabras de cuatro bits se quedaron pequeñas pronto, y rápidamente se pasó a palabras y a procesadores de 8 bits. La unidad de 8 bits se conoce como octeto o byte, y este tamaño tuvo tanto éxito que sigue siendo hoy en día la unidad básica para acceder a memoria.
Procesadores posteriores usan palabras que agrupaban bytes, los de 16 bits usan dos bytes, los de 32 usan cuatro bytes, y los de 64 ocho bytes. Sin embargo, se sigue usando una dirección de memoria para cada byte.
Los primeros procesadores eran en realidad máquinas calculadoras programables, es decir, sólo manejaban números y se usaban para realizar cálculos numéricos complejos o repetitivos. Pero según fue aumentando la complejidad de las máquinas, surgieron nuevas posibilidades, como proporcionar salidas más cómodas para las personas.
Pero los ordenadores siguen manipulado sólo números, por lo que había que inventar algo para que pudieran manejar letras y palabras. La solución es simple, y consiste en codificar cada letra mediante un valor numérico. De este modo nació el código ASCII.
El primer código ASCII almacenaba cada letra en un byte, pero usaba sólo 7 bits, dejando el octavo para añadir un bit de control de errores, que permite detectar fallos en las transmisiones de datos. Este bit se llama bit de paridad, y funciona del modo siguiente:
Para cada código ASCII se suman los bits con valor 1, si se usa un control de paridad par la suma de los bits en cada byte debe ser par (contando el bit de paridad), si se usa un control de paridad impar, la suma debe ser impar.
De todos modos, con siete bits se pueden codificar 128 caracteres, que según las personas que diseñaron el código, eran más que suficientes. Esto permite codificar los 10 digitos numéricos, los 25 caracteres del alfabeto inglés en mayúsculas, otros 25 para las minúsculas, 32 para caracteres destinados a símbolos, paréntesis, y signos de puntuación, el espacio. El resto, hasta 127 (33 caracteres), se usaron para codificar caracteres no imprimibles, que permiten formatear texto: retornos de línea, avances y retrocesos de caracteres, caracteres destinados a protrocolos de transmisión, etc.
Tabla ASCII correspondiente a los primeros 32 caracteres y al último. Estos son los no imprimibles:
Código binario | Código decimal | Abreviatura | Nombre |
---|---|---|---|
00000000 | 0 | NUL | Caracter Nulo (NULL) |
00000001 | 1 | SOH | Inicio de Encabezado (Start Of Header) |
00000010 | 2 | STX | Inicio de Texto (Start Text) |
00000011 | 3 | ETX | Fin de Texto (End Text) |
00000100 | 4 | EOT | Fin de Transmisión (End Of Transmision) |
00000101 | 5 | ENQ | Pregunta (Enquiry) |
00000110 | 6 | ACK | Reconocimiento (Acknowledgement) |
00000111 | 7 | BEL | Timbre (Bell) |
00001000 | 8 | BS | Retroceso (Back Space) |
00001001 | 9 | HT | Tabulación horizontal (Horizontal Tab) |
00001010 | 10 | LF | Avance de Línea (Line feed) |
00001011 | 11 | VT | Tabulación Vertical (Vertical Tab) |
00001100 | 12 | FF | Salto de página (Form feed) |
00001101 | 13 | CR | Retorno de carro (Carriage return) |
00001110 | 14 | SO | Salida de turno (Shift Out) |
00001111 | 15 | SI | Entrada de turno (Shift In) |
00010000 | 16 | DLE | Escape de enlace de datos (Data Link Escape) |
00010001 | 17 | DC1 | Device Control 1 — oft. XON |
00010010 | 18 | DC2 | Device Control 2 |
00010011 | 19 | DC3 | Device Control 3 — oft. XOFF |
00010100 | 20 | DC4 | Device Control 4 |
00010101 | 21 | NAK | Reconocimiento negativo (Negative Acknowledgement) |
00010110 | 22 | SYN | Sincronismo sin usar (Synchronous Idle) |
00010111 | 23 | ETB | Fin de transmisión de bloque (End of Trans. Block) |
00011000 | 24 | CAN | Cancelar (Cancel) |
00011001 | 25 | EM | Fin de soporte (End of Medium) |
00011010 | 26 | SUB | Sustituto (Substitute) |
00011011 | 27 | ESC | Escape |
00011100 | 28 | FS | Separador de fichero (File Separator) |
00011101 | 29 | GS | Separador de grupo (Group Separator) |
00011110 | 30 | RS | Separador de registro (Record Separator) |
00011111 | 31 | US | Separador de unidad (Unit Separator) |
01111111 | 127 | DEL | Borrar (Delete) |
Tabla ASCII correspondiente a los caracteres imprimibles:
Binario | Decimal | Carácter | Binario | Decimal | Carácter | Binario | Decimal | Carácter |
---|---|---|---|---|---|---|---|---|
00100000 | 32 | espacio | 01000000 | 64 | @ | 01100000 | 96 | ` |
00100001 | 33 | ! | 01000001 | 65 | A | 01100001 | 97 | a |
00100010 | 34 | " | 01000010 | 66 | B | 01100010 | 98 | b |
00100011 | 35 | # | 01000011 | 67 | C | 01100011 | 99 | c |
00100100 | 36 | $ | 01000100 | 68 | D | 01100100 | 100 | d |
00100101 | 37 | % | 01000101 | 69 | E | 01100101 | 101 | e |
00100110 | 38 | & | 01000110 | 70 | F | 01100110 | 102 | f |
00100111 | 39 | ' | 01000111 | 71 | G | 01100111 | 103 | g |
00101000 | 40 | ( | 01001000 | 72 | H | 01101000 | 104 | h |
00101001 | 41 | ) | 01001001 | 73 | I | 01101001 | 105 | i |
00101010 | 42 | * | 01001010 | 74 | J | 01101010 | 106 | j |
00101011 | 43 | + | 01001011 | 75 | K | 01101011 | 107 | k |
00101100 | 44 | , | 01001100 | 76 | L | 01101100 | 108 | l |
00101101 | 45 | - | 01001101 | 77 | M | 01101101 | 109 | m |
00101110 | 46 | . | 01001110 | 78 | N | 01101110 | 110 | n |
00101111 | 47 | / | 01001111 | 79 | O | 01101111 | 111 | o |
00110000 | 48 | 0 | 01010000 | 80 | P | 01110000 | 112 | p |
00110001 | 49 | 1 | 01010001 | 81 | Q | 01110001 | 113 | q |
00110010 | 50 | 2 | 01010010 | 82 | R | 01110010 | 114 | r |
00110011 | 51 | 3 | 01010011 | 83 | S | 01110011 | 115 | s |
00110100 | 52 | 4 | 01010100 | 84 | T | 01110100 | 116 | t |
00110101 | 53 | 5 | 01010101 | 85 | U | 01110101 | 117 | u |
00110110 | 54 | 6 | 01010110 | 86 | V | 01110110 | 118 | v |
00110111 | 55 | 7 | 01010111 | 87 | W | 01110111 | 119 | w |
00111000 | 56 | 8 | 01011000 | 88 | X | 01111000 | 120 | x |
00111001 | 57 | 9 | 01011001 | 89 | Y | 01111001 | 121 | y |
00111010 | 58 | : | 01011010 | 90 | Z | 01111010 | 122 | z |
00111011 | 59 | ; | 01011011 | 91 | [ | 01111011 | 123 | { |
00111100 | 60 | < | 01011100 | 92 | \ | 01111100 | 124 | | |
00111101 | 61 | = | 01011101 | 93 | ] | 01111101 | 125 | } |
00111110 | 62 | > | 01011110 | 94 | ^ | 01111110 | 126 | ~ |
00111111 | 63 | ? | 01011111 | 95 | _ | |||
Bueno, creo que ahora queda más claro por qué se puede usar un valor entero como un carácter o como un número. Dentro de un ordenador no existe diferencia entre ambas cosas.
El valor 65 puede ser un número entero, o, si se interpreta como un carácter, puede ser la letra 'A'.
Pero aún nos queda un detalle importante: el signo. Cuando hemos hablado de variables de tipo char hemos comentado que pueden ser con y sin signo. Veamos cómo se las arregla el ordenador con los signos.
Lo primero que podemos decir del signo es que hay dos posibilidades: puede ser positivo o negativo. Esto parece hecho a la medida de un bit, de modo que podemos usar un único bit para indicar el signo, de modo que un valor 0 indica que se trata de un número positivo y un 1 de un número negativo.
Esta es la primera solución, podemos usar el bit más a la izquierda para codificar el signo. Con un número de ocho bits, eso nos deja siete para codificar el valor absoluto, es decir, 127 valores posibles positivos y otros tantos negativos.
Pero esta solución tiene dos inconvenientes:
Existe una solución mejor que mantiene la codificación del bit de signo, pero que elimina estos dos inconvenientes. Se trata de la codificación conocida como "complemento a dos".
Pero antes de ver qué es el complemento a dos, veamos qué es el complemento a uno. El complemento a uno consiste, en tomar un número en binario y cambiar los ceros por unos y los unos por ceros.
El complemento a uno de 01001010 es 10110101.
El complemento a dos consiste en hacer el complemento a uno y sumar 1 al resultado.
Ya sabemos sumar, espero, con números en base diez. Con números en base dos es igual de fácil. La tabla de sumar en binario es:
Por ejemplo:
111111
01101011
+ 00110110
----------
10100001
Sigamos con el complemento a dos. Para el ejemplo anterior, el complemento a dos de 01001010 sería 10110101+1:
1
10110101
+ 00000001
----------
10110110
Lo primero que vemos es que cuando se hace el complemento a dos de cualquier número, el signo cambia. Otra cosa que podemos ver es que el complemento a dos del cero es cero.
Complemento a uno de 00000000 es 11111111, y sumando 1 tenemos:
11111111 11111111 + 00000001 ---------- 100000000
El uno de la izquierda no cuenta, ya que sólo tenemos ocho bits, el noveno se pierde, y el resultado es cero.
Pero lo mejor de todo es que la suma de cualquier número con su complemento a dos es siempre cero:
1111111 01001010 + 10110110 ---------- 100000000
Esto es una gran ventaja, ya que podemos usar esta propiedad para decir que el complemento a dos equivale a cambiar el signo de un número, ya que la suma de un número y su complemento es cero, y el complemento de cero es cero.
Esto además nos da otra pequeña ventaja. Al tener una sóla combinación para el cero, tenemos un valor extra, de modo que el valor positivo máximo es 127 (01111111), pero para los negativos podemos llegar hasta el -128 (10000000).
Así, si usamos una variable char sin signo para almacenar números, podremos manejar valores entre 0 y 255. Si usamos variables char con signo, los valores posibles estarán entre -128 y 127.
Hola. Me estoy iniciando en la programación en C++ y la verdad es que tengo muchísimas dudas. Ya leí bastante capítulos pero cuando veo los comentarios de la gente y como resuelve los problemas yo no comprendo nada. Por momentos me da ganas de dejar esto porque pienso que si no lo entiendo es que no es lo mio. Son bastantes datos. Por poner un ejemplo, algo que no entiendo es cuando haces:
#include <stdio.h>
#include <math.h>
int main()
{
double x = 0.2345;
printf( "acos( %f ) = %f\n", x, acos(x) );
return 0;
}
No sé porque pones el operador binario % al lado de la letra f, si yo el ejemplo que leí lo entendí muy bien porque lo usaste en la división 17/7 y si se usa el % el resultado es el resto de esa división. Pero viendo lo que hiciste arriba ya me perdí del todo. Gracias de antemano por la ayuda
int residuo = 9 % 5;
Aquí, % es un operador binario que da el residuo de una división.
printf( "acos( %f ) = %f\n", x, acos(x) );
En este caso, % no es un operador binario, sino que es un carácter, como la letra 'a'.
En la función printf (y en scanf), % se utiliza para decir que ahí va una variable. "%f" es para poner un número con decimales (float, double), que pones después.
printf("Peso: %f", 51.031); // En la pantalla verás: Peso: 51.031 printf("%"); // En la pantalla verás: %
No sé si me explico, pero sería, resumido, que aquí % está dentro de una cadena de caracteres. Del mismo modo que:
char c = '%'
no se refiere al operador %, lo de antes tampoco.
La neta el pendejo eres tu, por que la diferencia entre ser un programador bueno y un programador mierda es conocer la teoría y saber como es que la computadora funciona internamente, ademas no es tan difícil de entender y si no lo entiendes es mejor que toques tu guitarrita por que no esto para ti la programación no es para las personas que quieren que las cosas digeridas y facilitas es parte del desarrollo de un razonamiento lógico.
La neta el pendejo eres tu, por que la diferencia entre ser un programador bueno y un programador mierda es conocer la teoría y saber como es que la computadora funciona internamente, ademas no es tan difícil de entender y si no lo entiendes es mejor que toques tu guitarrita por que esto no es para ti, la programación no es para las personas que quieren las cosas digeridas y facilitas es parte del desarrollo de un razonamiento lógico.
NECESITO AYUDA PARA CREAR UN PROGRAMA EL CUAL ME IMPRIMA UN LETRERO EL CUAL DIGA 'HOLA' Y DESPUES UNA INICIAL. CON VARIABLE 'CHAR'. SOLO TENGO ESTO PERO NOSE PORQUE NO ME IMPRIMA LA LETRA:
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
int main()
{
char letrero; //Definición de una variable tipo caracter
char nombre[$]; //Definición de variable tipo caracter numero 2
char total; //Definición de variable tipo caracter numero 3
cout<<"Dame el letrero "; //Lectura de la variable tipo caracter
cin>>letrero;
total=letrero + nombre;
cout<<total;
cin>>total;
getch();
return 0;
}
Buenas tardes. Me gusto su pagina, muy interesante, aporta muchas cosas a las que era ignorante. Mil gracias
Y necesito una ayuda !!!
No me quiere ejecutar el siguiente programa, no encuentro el error, le agradecería que me colaborara
Nose si es necesario incluir la biblioteca de include<stdlib.h>
?
#include<stdio.h>
#include<stdlib.h>
main ()
{
int opcion;
char i;
printf( "Seleccione como quiere el abecedario\n" );
printf( "\n\t 1. Ascendente \n\t 2. Descendente\n" );
scanf( "%i", &opcion );
swintch ( opcion )
{
case 1: i='A';
while ( i<='Z' )
{
printf( "%c", i );
i ++;
}
break;
case 2;
for ( i='Z'; i>='A'; i--)
{
printf( "%c", i );
i++;
}
break;
default: printf( "La opcion es incorrecta\n" );
}
system( "cls" );
}
Hola Angie,
Sí necesitas incluir <stdlib.h> porque usas la función 'system()'.
El error de compilación es al escribir:
case 2;
cuando debería ser:
case 2:
Es decir, has escrito un punto y coma en lugar de dos puntos.
Espero que esto te oriente.
Steven
¿el complemento de 01001010 es igual a : 10110101?
Me interesa muchisimo el curso de c++ ,yo e aprendido algo en la escuela pero esto es mejor
cuales son las funciones que aceptan las tildes y a la letra ñ en c++
© Junio de 2007, Salvador Pozo, salvador@conclase.net