Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Algoritmos
3.1 Algoritmos
Un algoritmo es un método paso a paso para resolver algunos problemas. En la actualidad,
“algoritmo” suele referirse a una solución ejecutable por una computadora. Es decir, un algoritmo
es un conjunto finito de instrucciones precisas que sirve para realizar un cálculo o resolver un problema.
Hay que hacer énfasis en dos aspectos para que un algoritmo exista:
1. El número de pasos debe ser finito. De esta manera el algoritmo debe terminar en un tiempo
finito con la solución del problema,
2. El algoritmo debe ser capaz de determinar la solución del problema.
De este modo, podemos definir algoritmo como un conjunto de reglas operacionales inherentes a un
cómputo. Se trata de un método sistemático, susceptible de ser realizado mecánicamente, para resolver
un problema dado.
Los algoritmos no son exclusivos de la informática. También son algoritmos los que aprendemos en
el colegio para multiplicar y dividir números de varias cifras. De hecho, el algoritmo más famoso de la
historia es el algoritmo de Euclides para calcular el máximo común divisor.
1
La idea del algoritmo es inspeccionar los números uno por uno y copiar el valor más grande
encontrado a la variable grande. En la conclusión del algoritmo, grande será igual al valor mayor
de los tres números.
Ahora se muestra la manera en que el algoritmo anterior se ejecuta para algunos valores especı́ficos
de a, b y c. Esta simulación se llama seguimiento o rastreo. Primero supongamos que a = 1, b = 5, c = 3.
En la lı́nea 1, grande tiene el valor de a (1). En la lı́nea 2, b > grande (5 > 1) es verdadera, de
manera que grande es igual a b (5). En la lı́nea 3, c > grande (3 > 5) es falsa, y no hay cambio. En
este punto grande es 5, el valor mayor entre a, b y c.
Supongamos que a = 6, b = 1, c = 9.
En la lı́nea 1, grande tiene el valor de a (6). En la lı́nea 2, b > grande (1 > 6) es falsa, y no hay
cambio. En la lı́nea 3, c > grande (9 > 6) es verdadera, de manera que grande es igual a 9. En este
punto grande es 9, el valor mayor entre a, b y c.
Se verifica que el ejemplo de algoritmo tiene las caracterı́sticas establecidas al inicio de esta sección.
El algoritmo recibe los tres valores a, b y c como entrada y produce el valor grande como salida.
Los pasos del algoritmo se establecen con suficiente precisión de manera que éste puede escribirse
en un lenguaje de programación y ser ejecutado por una computadora.
A partir de los valores de entrada, cada paso intermedio de un algoritmo produce un resultado único.
El algoritmo termina después de un número finito de pasos (tres pasos) y contesta correctamente la
pregunta planteada (encontrar el mayor de tres valores de entrada).
El algoritmo es general; permite encontrar el valor más grande de cualesquiera tres números.
Aunque el lenguaje común en ocasiones es adecuado para especificar un algoritmo, la mayorı́a de los
matemáticos y los especialistas en ciencias de la computación prefieren el seudocódigo por su precisión,
estructura y universalidad. El seudocódigo recibe este nombre porque se parece a un código real en
lenguaje de computadora, como C ++ . Existen muchas versiones de seudocódigo. A diferencia de los
lenguajes para computadora que deben preocuparse por puntos y comas, mayúsculas y minúsculas,
palabras reservadas y otros elementos, cualquier versión de seudocódigo es aceptable siempre y cuando
sus instrucciones no sean ambiguas.
Ejemplo 3.2. Encontrar el valor máximo en una sucesión finita de numeros. Usar el método del
ejemplo anterior.
Solución Pongamos Entrada: s,n
Salida: grande(el valor mayor en una sucesión s)
máx(s,n){
grande = s1
for i = 2 to n
if(si > grande)
grande = si
return grande
}
Un algoritmo puede ser caracterizado por una función lo cual asocia una salida: s = f (E) a cada
entrada E.
Se dice entonces que un algoritmo calcula una función f . Entonces la entrada es una variable
independiente básica en relación a la que se producen las salidas del algoritmo, y también los análisis
de tiempo y espacio.
Cuando se tiene un problema para el cual debemos especificar un algoritmo solución, tendremos en
cuenta varios puntos:
1. Si no se conoce un método para solucionar el problema en cuestión, debemos hacer un análisis del
mismo para llegar a una solución, después de evaluar alternativas, exigencias y excepciones.
4. En algún sentido, en general, un método para solucionar todos los problemas de un conjunto dado,
se considera superior a un método para solucionar solamente un problema del conjunto.
2
5. Hay criterios para determinar que tan buena es una solución, distintos de ver si trabaja o no, o
hasta qué punto es general la aplicabilidad del método. Estos criterios involucran aspectos tales
como: eficiencia, elegancia, velocidad, etc.
Al definir con exactitud un método de solución para un problema, este debe estar en capacidad de
encontrarla si existe; en caso de que no exista, el método debe reconocer esta situación y suspender
cualquier acción.
No se enseña nunca técnicas de cómo resolver problemas en general.
Al movernos dentro de la informática no siempre encontramos los problemas a punto de resolverlos,
es necesario empezar por hacer su formulación. Se exige hacerlo en términos concisos y claros partiendo
de las bases o supuestos que se dispone para especificar sus requerimientos.
Sólo a partir de una buena formulación será posible diseñar una estrategia de solución. Es necesario
aprender a desligar estos dos procesos. No se deben hacer formulaciones pensando paralelamente en
posibles soluciones. Es necesario darle consistencia e independencia para determinar con precisión a
qué se quiere dar solución y luego canalizar una gama de alternativas posibles.
Si ya se ha realizado la formulación del problema podemos cuestionarla con el fin de entenderlo bien.
En nuestra área, el análisis de un problema tiene dos etapas claramente definidas y relacionadas:
Definición del problema
1. Formulación o planteamiento del problema Supuestos: aserciones y limitaciones dadas
Resultados esperados
Análisis de alternativas y selección de la solución.
Especificación detallada del procedimiento solución.
2. Resolución del problema
Adopción o uso de una herramienta para su
implementación, si es necesária.
3
de la cadena p = “Matemáticas Discretas” en t) o determinar que p no aparece en t. Se indexan los
caracteres en t comenzando con 1. Un enfoque para buscar p es verificar si p ocurre en el ı́ndice 1 en t.
Si ası́ es, nos detenemos, puesto que ya se encontró la primera ocurrencia de p en t. Si no, se verifica si
p ocurre en el ı́ndice 2 en t. Si ası́ es, nos detenemos, pues ya se encontró la primera ocurrencia de p en
t. Si no, se verifica el ı́ndice 3 en t, y ası́ sucesivamente.
El algoritmo de búsqueda de texto es el siguiente, como ejemplo:
Ejemplo 3.3. Búsqueda de texto. Este algoritmo busca una ocurrencia del patrón p en el texto t.
Regresa el ı́ndice más pequeño i tal que p ocurre en t comenzando en el ı́ndice i. Si p no ocurre en t,
regresa 0.
Entrada: p (indexada de 1 a m), m, t (indexada de 1 a n), n
Salida: i
busca texto(p, m, t, n){
for i = 1 to n - m + 1{
j=1
// i es el ı́ndice en t del primer carácter de la subcadena para comparar con p, y j es el
ı́ndice en p
// el ciclo “while” compara ti . . . ti+m−1 y p1 . . . pm
while (ti+j−1 == pj ){
j=j+1
if(j > m)
return i
}
}
return 0
}
La variable i marca el ı́ndice en t del primer carácter de la subcadena para compararlo con p. El
algoritmo primero intenta i = 1, después i = 2, y ası́ sucesivamente. El ı́ndice n − m + 1 es el último
valor posible para i ya que, en este punto, la cadena tn−m+1 tn−m+2 · · · tm tiene la longitud exacta m.
Después de establecer el valor i, el ciclo “while” compara ti ...ti+m−1 y p1 ...pm . Si los caracteres
coinciden,
ti+j−1 ̸= pj
j se incrementa
j =j+1
y se comparan los siguientes caracteres. Si j es m + 1, todos los m caracteres coinciden y hemos
encontrado p en el ı́ndice i en t. En este caso, el algoritmo regresa i:
if (j > m)
return i
Si el ciclo corrió hasta completarse, nunca se encontró una coincidencia, en cuyo caso el algoritmo
regresa 0.
4
El tamaño de un ejemplar x corresponde formalmente al número de dı́gitos binarios necesarios para
representarlo en el computador. Pero a nivel algorı́tmico consideraremos el tamaño como el número de
elementos lógicos contenidos en el ejemplar.
Un algoritmo es eficiente cuando logra llegar a sus objetivos planteados utilizando la menor cantidad
de recursos posibles, es decir, minimizando el uso memoria, de pasos y de esfuerzo humano.
Un algoritmo es eficaz cuando alcanza el objetivo primordial, el análisis de resolución del problema
se lo realiza prioritariamente.
Puede darse el caso de que exista un algoritmo eficaz pero no eficiente, en lo posible debemos de
manejar estos dos conceptos conjuntamente.
La eficiencia de un programa tiene dos ingredientes fundamentales: espacio y tiempo.
Ambas dependen del tipo de computador y compilador, por lo que veremos la eficiencia de los
programas, sino la eficiencia de los algoritmos. Asimismo, este análisis dependerá de si trabajamos con
máquinas de un solo procesador o de varios de ellos.
Centraremos nuestra atención en los algoritmos para máquinas de un solo procesador que ejecutan
una instrucción y luego otra.
Como hemos visto, existen muchos enfoques para resolver un problema. ¿Cómo escogemos entre
ellos? Generalmente hay dos metas en el diseño de programas de cómputo:
• El diseño de un algoritmo que sea fácil de entender, codificar y depurar (Ingenierı́a de Software).
• El diseño de un algoritmo que haga uso eficiente de los recursos de la computadora (Análisis y
Diseño de algoritmos).
los extremos son habitualmente conocidos como caso peor y caso mejor.
Entre ambos se hallará algún caso promedio o más frecuente.
Cualquier fórmula f (n) incluye referencias al parámetro n y a una serie de constantes ”fi ” que
dependen de factores externos al algoritmo como pueden ser la calidad del código generado por el
compilador y la velocidad de ejecución de instrucciones del computador que lo ejecuta.
No se puede medir el tiempo en segundos porque no existe un computador estándar de referencia,
en su lugar medimos el número de operaciones básicas o elementales: suma, resta, multiplicación,
división y comparaciones que se indican explı́citamente en un enunciado si emplean uno de los sı́mbolos
relacionales <, ≤, >, ≥, = o ̸=.
Cuando se implementan los algoritmos en un particular lenguaje de programación y se ejecutan
en una determinada computadora, entonces algunas operaciones se efectúan más rápido que otras y,
de hecho, de una máquina a otra hay diferencias en los tiempos de ejecución. En ciertas situaciones
prácticas esos factores se toman en cuenta al decidir qué algoritmo o que máquina emplear para resolver
un problema especı́fico.
5
Sin embargo, en otros casos la máquina es dada y todo lo que necesitamos son burdas estimaciones
para determinar la clara superioridad de un algoritmo sobre otro. Como cada operación elemental se
ejecuta en un tiempo no mucho mayor que la más lenta, entonces la eficiencia temporal de un algoritmo
es aproximadamente proporcional al número de operaciones elementales requerido para ejecutar el
algoritmo.
Considere el ejemplo de dos algoritmos, A y B, diseñados para realizar cierto trabajo.
Supongamos que para una entrada de tamaño n, el número de operaciones elementales que se
necesitan para realizar el algoritmo A está entre 10n y 20n (al menos para n grandes) y que el número
de operaciones elementales requeridas para ejecutar el algoritmo B está entre 2n2 y 4n2 .
Observe que 20n < 2n2 siempre que n > 10, lo que significa que el número máximo de operaciones
necesitadas para ejecutar A es menor que el número mı́nimo de operaciones requeridas para implementar
B siempre que n > 10.
En efecto, 20n es mucho menor que 2n2 cuando n es grande. Por ejemplo, si n = 1000, entonces
20n = 20000 mientras que 2n2 = 2000000. Decimos que en el peor caso, el algoritmo A es Θ(n) (o que
tiene un peor caso de orden n) y el algoritmo B es Θ(n2 )(o que tiene un peor caso de orden n2 ).
Todo esto último se conoce como el crecimiento de funciones.
Frecuentemente ocurre que, de entre varios algoritmos, se podrı́a emplear uno para ejecutar cierto
trabajo, pero el tiempo o la capacidad de memoria que requieren varı́an dramáticamente. Las notaciones
O, Ω y Θ dan aproximaciones que hace fácil evaluar diferencias a gran escala en la eficiencia de un
algoritmo, mientras que se ignoran diferencias de un factor constante y diferencias que suceden sólo
para pequeños conjuntos de datos de entrada.
La más antigua de las notaciones, la O-notación (o la notación O), fue introducida por el matemático
alemán Paul Bachmann en 1894 en un libro sobre teorı́a analı́tica de números. Las notaciones Ω (Omega)
y Θ (Theta) fueron desarrolladas por Donald Knuth, uno de los pioneros de la ciencia de programación
computacional.
La idea de las notaciones es esta. Suponga que f y g son funciones reales de una variable real x.
1. Si, para valores de x suficientemente grandes, los valores de |f | son menores que los de un múltiplo
de |g|, entonces f es de orden a lo más g, o f (x) es O(g(x)).
|f | ≡ |f (x)|
|f (x)| ≤ |g (x)|
2. Si, para valores de x suficientemente grandes, los valores de |f | son más grandes que los de un
múltiplo de |g|, entonces f es de orden al menos g, o f (x) es Ω(g(x)).
α |g (x)| ≤ |f (x)|
3. Si, para valores de x suficientemente grandes, los valores de |f | están acotados por arriba y por
abajo por valores múltiplos de |g|, entonces f es de orden g, o f (x) es Θ(g(x)).
Sean f y g funciones valuadas en los reales sobre el mismo conjunto de números reales no-negativos.
Entonces
1. f es de orden al menos g, y se escribe f (x) es Ω(g(x)), si y sólo si, existen un número real positivo
A y un número real no-negativo a tales que
A |g (x)| ≤ |f (x)|
6
2. f es de orden a lo más g, y se escribe f (x)es O(g(x)), si y sólo si, existen un número real positivo
B y un número real no-negativo b tales que
|f (x)| ≤ B |g (x)|
Ejemplo 3.4. Dado que 60n2 + 5n + 1 ≤ 60n2 + 5n2 + n2 = 66n2 para toda n ≥ 1, se puede tomar
B = 66 en la definición para obtener
60n2 + 5n + 1 = O(n2 ).
Como
60n2 + 5n + 1 ≥ 60n2
para toda n ≥ 1, se puede tomar A = 60 en la definición para obtener
60n2 + 5n + 1 = Ω(n2 ).
60n2 + 5n + 1 = Θ(n2 ).
2n + 3 log2 n < 2n + 3n = 5n
para toda n ≥ 1. Ası́,
2n + 3 log2 n = O(n).
Además,
2n + 3 log2 n ≥ 2n
para toda n ≥ 1. Entonces,
2n + 3 log2 n = Ω(n).
Por lo tanto,
2n + 3 log2 n = Θ(n).
Ejemplo 3.6. Use la notación Θ para expresar el enunciado
7
Observación 3.9. El punto 3. del ejemplo 3.8 muestra el hecho de que si sabe que f es de orden a lo
más g y que f es de orden a lo menos g, entonces puede tomar k como el mayor de los números a y
b como se prometió en las definiciones de las notaciones omega y O y ası́ concluir que f es de orden
g. Inversamente, si f es de orden g, entonces a y b pueden tomarse como el número k prometido en la
definición de la notación theta, para ası́ demostrar que f es del orden a lo más g y que f es del orden
a lo menos g. Esos resultados y una propiedad transitiva de orden, se establecen formalmente en el
siguiente teorema.
Propiedades de las notaciones O, Ω y Θ
Sean f y g funciones valuadas en los reales definidas sobre el mismo conjunto de números reales
no-negativos.
1. f (x) es Ω(g(x)) y f (x) es O(g(x)) si y sólo si, f (x) es Θ(g(x)).
2. f (x) es Ω(g(x)) si y sólo si, g(x) es O(f (x)).
3. Si f (x) es O(g(x)) y g(x) es O(h(x)), entonces f (x) es O(h(x)).
Se dice que O(f (n)) define un orden de complejidad. Escogeremos como representante de este orden a
la función f (n) más sencilla del mismo.
Ası́ tendremos:
O(1) orden constante
8
O(log n) orden logarı́tmico (búsqueda binaria)
O(n) orden lineal
O(n2 ) orden cuadrático (ordenamiento burbuja)
O(na ) orden polinomial (a > 2)
O(an ) orden exponencial (a > 2)
O(n!) orden factorial
Se puede identificar una jerarquı́a de órdenes de complejidad que coincide con el orden de la tabla
anterior; jerarquı́a en el sentido de que cada orden de complejidad superior tiene a los inferiores como
subconjuntos. Si un algoritmo A se puede demostrar de un cierto orden O1 , es cierto que también
pertenece a todos los órdenes superiores; pero en la práctica lo útil es encontrar la ”menor cota superior”,
es decir el menor orden de complejidad que lo cubra.
En el análisis de algoritmos se considera usualmente el caso peor, si bien a veces conviene analizar
igualmente el caso mejor y hacer alguna estimación sobre un caso promedio. Para independizarse de
factores coyunturales, tales como el lenguaje de programación, la habilidad del codificador, la máquina
de soporte, etc. se suele trabajar con un cálculo asintótico que indica cómo se comporta el algoritmo
para datos muy grandes y salvo algún coeficiente multiplicativo. Para problemas pequeños casi todos
los algoritmos son ”más o menos iguales”, primando otros aspectos como esfuerzo de codificación,
legibilidad, etc. Los órdenes de complejidad son importantes para grandes problemas.
A este número |x| en el Teorema 3.11 que sigue lo escribimos como n, los |xi | los escribimos como ai .
Por lo general, los dı́gitos hexadecimales utilizados son 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E y F ,
donde las letras de la A a la F representan los dı́gitos correspondientes a los números del 10 al 15 (en
notación decimal).
Por ejemplo,
3854 = 3 · 103 + 8 · 102 + 5 · 101 + 4 · 100
En el sistema numérico binario (base 2), para representar enteros se necesitan sólo dos sı́mbolos, 0 y 1.
Para representar un entero, leyendo de derecha a izquierda, el primer sı́mbolo representa el número de
unos, el siguiente sı́mbolo el número de números dos, el siguiente el número de cuatros, el siguiente el
número de ochos, etc. Por ejemplo, en base 2,
101101 = 1 · 25 + 0 · 24 + 1 · 23 + 1 · 22 + 0 · 21 + 1 · 20
9
En general, tenemos el siguiente teorema.
Teorema 3.11. Sea b un número entero mayor que 1. Entonces, si n es un número entero positivo,
este puede expresarse de manera única en la forma n = ak bk + ak−1 bk−1 +· · · +a1 b + a0 , donde k es
un entero no negativo, a0 , a1 , ..., ak son enteros no negativos menores que b, y ak ̸= 0.
En el teorema b se llama la base y la expresión para el entero n, se llama la representación en la
base b.
Ejemplo 3.12. Expresar el número 27 en base dos.
Ejemplo 3.13. Representar 209 en base 2.
n = bq0 + a0 , 0 ≤ a0 < b.
Algunos algoritmos
Algunos algoritmos
10
Salida: c, n
dec a base b(m, b, c, n){
n = –1
while(m > 0){
n=n+1
cn = m mod b
m = ⌊m/b⌋
}
}
que usa n−1 multiplicaciones. Se logran mejores resultados si se eleva al cuadrado repetidas veces.
Ejemplo 3.20. Calcular a29 .
Solución
Primero se calcula a2 = a · a, que requiere una multiplicación. Después se calcula a4 = a2 · a2 ,
que usa una multiplicación más. Luego se calcula a8 = a4 ·a4 , que usa una multiplicación adicional y
después se calcula a16 = a8 ·a8 , que requiere una multiplicación más. Hasta aquı́ se han empleado sólo
4 multiplicaciones. Observe que la expansión de 29 en potencias de 2, que es la expansión binaria, es
29 = 1 + 4 + 8 + 16,
11
vemos que se puede calcular a29 como
a29 = a1 · a4 · a8 · a16 ,
que usa 3 multiplicaciones adicionales con un total de 7 multiplicaciones. La técnica directa utiliza 28
multiplicaciones.
En el ejemplo 3.12, (representar 209 en base 2) se vio que los residuos, cuando n se divide repetidas
veces entre 2, dan la expansión binaria de n. Si el residuo es 1, se incluye la potencia de 2 correspondiente;
de otra manera, no se incluye.
Se puede formalizar la técnica de elevar al cuadrado repetidas veces si se determina al mismo tiempo
la expansión binaria del exponente.
La tabla que sigue muestra cómo se calcula a29 elevando al cuadrado una y otra vez. Inicialmente,
x se hace igual a a, y n al valor del exponente, en este caso 29. Después se calcula n mod 2. Como este
valor es 1, se sabe que 1 = 20 está incluido en la expansión binaria de 29. Por lo tanto, a1 se incluye
en el producto. Se da seguimiento al producto parcial en el resultado; ası́, el resultado se hace igual a
a. Luego se calcula el cociente cuando 29 se divide entre 2. El cociente 14 se vuelve el nuevo valor de
n. Después se repite este proceso.
12
n = ⌊n/2⌋
}
return resultado
}
N = Ne + Nf
Cb (N ) = (10k · · · 01 ) − N
13
Ejemplo 3.32. Hallar el complemento a 1 de 10112
Ejemplo 3.33. Encontrar el complemento a 1 de 10102
Representación de Datos en el computador
Los datos pueden ser
1. Numéricos
2. Alfanuméricos.
1. Numéricos
(a) Enteros
Normalmente utilizamos el sı́mbolo “−” precediendo a un número para indicar que éste es
menor que cero. Esta es una notación muy práctica en la vida cotidiana pero no puede ser
utilizada en la representación que se hace de los números en una computadora, recordemos
que sólo se pueden utilizar los dı́gitos binarios para representar cualquier cosa en ellas y el
“−” no es ningún bit.
Pero podemos utilizar la misma idea, preceder el número de un bit que indique su signo,
después de todo sólo hay dos posibles signos, a saber: “+” y “−”. Todo lo que tenemos que
hacer es asignar arbitrariamente un bit a cada signo. Convencionalmente se hace: “+”= 0,
“−”= 1.
A este método de representación de números negativos se le denomina signo y magnitud
porque, análogamente a lo que solemos hacer, se coloca un sı́mbolo que precede al número y
que indica su signo y luego se pone la magnitud del número. En esta notación por ejemplo
1 010102 = −1010
De esta manera es muy fácil distinguir los números positivos de los negativos, si utilizamos
un número fijo de bits para representarlos y decidimos que siempre el primer bit es para
el signo del número, entonces basta con observar el primer bit de la izquierda (al que en
este caso no podemos decirle formalmente “el más significativo”, dado que no tiene asociada
ninguna potencia de 2) para determinar si se trata de un número negativo o positivo.
En este caso la “multiplicación por −1” de un número equivale a negar o invertir el bit de
la extrema izquierda, esto es, convertirlo en cero si vale 1 y viceversa. De hecho la idea
fundamental detrás de la representación de signo y magnitud es que ocurra: −(−a) = a.
Lo que nos parece evidente por estar acostumbrados a nuestra representación de números
negativos convencional.
Un inconveniente del sistema de signo y magnitud es que existen dos representaciones distintas
para el cero, es decir, el neutro aditivo no es único formalmente hablando, tanto el 10...0
como el 00...0 son cero, el primero con signo “−” y el segundo con signo “+”, lo que tampoco
es correcto desde el punto de vista matemático, dado que el cero no es ni positivo ni negativo.
Esta dualidad del cero tiene implicaciones importantes en una computadora digital. Los
procesadores tienen generalmente instrucciones para cambiar al flujo de los programas llamadas
saltos, hay saltos incondicionales (siempre que el procesador ejecuta la instrucción de salto la
siguiente instrucción es aquella indicada por el salto) y hay saltos condicionales (la instrucción
siguiente es a veces la que está bajo la del salto y a veces la indicada por el salto dependiendo
de alguna condición). Y generalmente la condición de salto es establecida comparando algún
dato con cero. Si hay dos representaciones del cero hay que hacer dos comparaciones y eso
lleva más tiempo que hacer sólo una.
Enteros sin signo
Los enteros sin signo son representados como números en base dos. Si se dispone de n bits
se puede representar 2n enteros sin signo. Su rango es
0 ≤ N ≤ 2n − 1
14
Ejemplo Si se dispone de n = 4 bits, el cero se representa por 0000. El 15 se representa por
11112 .
Enteros con signo
Los enteros con signo se pueden representar en:
• Signo y magnitud.
• Complemento a uno.
• Complemento a dos.
• Exceso.
• Representación en signo y magnitud
Hay varias convenciones alternativas que se pueden utilizar para representar números
enteros tanto positivos como negativos. Todas ellas implican tratar el bit más significativo
(el más a la izquierda) de la palabra como un bit de signo: si dicho bit es 0 el número
es positivo, y si es 1, el número es negativo.
La forma más sencilla de representación que emplea un bit de signo es la denominada
representación signo-magnitud. En una palabra de n bits, los n − 1 bits de la derecha
representan la magnitud del entero.
Rango:
− 2n−1 − 1 ≤ N ≤ 2n−1 − 1
15
• Representación en Complemento a dos
Al igual que la de signo y magnitud, la representación en complemento a dos utiliza el bit
más significativo como bit de signo, facilitando la comprobación de si el entero es positivo
o negativo. Difiere de la representación signo-magnitud en la manera de interpretar los
bits restantes. La negación de un número es un proceso de dos pasos. Primero, cada 1
se sustituye por un 0 y cada 0 por un 1, igual que en el complemento a uno. Luego se
suma 1 al resultado. La suma binaria es igual a la suma decimal, excepto que se genera
un acarreo si la suma es mayor que 1, no si la suma es mayor que 9. Por ejemplo, la
conversión de 6 a complemento a dos se efectúa en dos pasos
00000110 (+6)
11111001 (−6 en complemento a uno)
11111010 (−6 en complemento a dos)
1000
+1
1001
1000
0111
+1
1000
16
En la tabla siguiente se dan, para n = 8 bits, una representación de algunos enteros
(b) Reales
Los reales se pueden representar en
i. Punto fijo.
ii. Notación Cientı́fica Decimal.
iii. Notación Cientı́fica Binaria.
iv. Notación Cientı́fica Binaria con mantisa normalizada.
1) Punto fijo
Se trabaja con un número fijo de decimales. Se utliza el primer bit de la izquierda para
representar el signo (cero para + y uno para -).
Se tiene un número fijo de bits para representar la parte entera y un número fijo de bits
para representar la parte decimal como enteros sin signo.
Ejemplo Se dispone de n = 32 bits, asignando 1 bit para el signo, 21 bits para la parte
entera y 10 bits para la parte decimal.
Como se dispone de 10 bits para representar la parte decimal y como 210 = 1024, entonces
se puede representar 3 decimales.
El 38.325 se representa por
0 000000000000000100110 0101000101
1 000000000000000100110 0101000000
0 000000000000000100110 0100101100
17
3) Notación Cientı́fica Binaria
Se expresa el número en notación cientı́fica binaria.
Se usa el primer bit de la izquierda para representar el signo (cero para + y uno para -).
Se tiene un número fijo de bits para representar el exponente en exceso y un número fijo
de bits para la mantisa.
Ejemplo Si se dispone de n = 32 bits, asignamos 1 bit para el signo, 7 bits para el
exponente y 24 bits para la mantisa.
Ası́, el −419.8125 se representa por
1 1001001 110100011110100000000000
1 1001001 101000111101000000000000
2) Alfanuméricos
Los caracteres alfanuméricos pueden ser dı́gitos, letras o caracteres especiales como los signos de
puntuación, de agrupamientos, matemáticos, gráficos, o de control.
Los caracteres son representados por cadenas binarias iguales al código asociado a cada caracter.
Las tablas más usuales son la ASCII y la tabla EBCDIC. ASCII es el Código Estándard Americano
para Intercambio de Información. Cada caracter ASCII tiene 7 bits, lo que permite representar
un total de 128 caracteres.
Hoy también existe un nuevo sistema llamado UNICODE, actualmente varios lenguajes de programación(como
Java), algunos sistemas operativos (como windows NT) y muchas aplicaciones reconocen UNICODE.
La idea en la que se basa UNICODE es asignar a cada caracter y sı́mbolo un valor único y
permanente de 16 bits, llamado punto de código. No se usan caracteres de múltiples bytes ni
sucesiones de escape. Al hacer que cada sı́mbolo tenga 16 bits la escritura de software se simplifica
mucho.
Con sı́mbolos de 16 bits, UNICODE tiene 65,356 puntos de código. Ya que los idiomas del mundo
emplean colectivamente unos 200,000 sı́mbolos, los puntos de código son un recurso escaso que
debe asignarse con mucho cuidado. Existe todo un trabajo centrado en los puntos de código que
faciliten la conversión entre ASCII y UNICODE.
18