Representación de números. Conversiones.

Anuncio
UNIVERSIDAD TECNICA FEDERICO SANTA MARIA
DEPARTAMENTO DE ELECTRONICA
Programación en Pascal
Capítulo 26. Representación de números. Conversiones.
26. Representación de números. Conversiones
26.1. Representación y conversión.
Los números son representados internamente, en un computador digital, en sistema binario.
Externamente se representan mediante secuencias de caracteres. Los procesos de entrada y
salida de números evidentemente están basados en procedimientos de conversión entre la
representación externa y la interna y viceversa.
Gran parte de las facilidades que un lenguaje de programación ofrece a un programador, se
encuentran en la abstracción de la representación interna de los números. Específicamente, en
Pascal, nos referimos a los procedimientos read y write con argumentos enteros y reales.
Asumiremos que se dispone de procedimientos para leer y escribir caracteres.
26.2 Funciones primitivas.
Se desarrollan algunas funciones primitivas que nos serán útiles.
function esdigito(ch:char):boolean;
begin
esdigito:=('0'<=ch) and (ch<='9')
end;
function valor(ch:char):integer;
begin
valor:=ord(ch)-ord('0')
end;
function caracter(x:integer):char;
begin
caracter:=chr(x+ord('0'))
end;
Debe asegurarse que el argumento de caracter esté en el rango:
0 <= x < 10
Prof. Leopoldo Silva Bijit.
07-07-2003
308
UNIVERSIDAD TECNICA FEDERICO SANTA MARIA
DEPARTAMENTO DE ELECTRONICA
Programación en Pascal
Capítulo 26. Representación de números. Conversiones.
26.3 Lectura de enteros.
En sistemas posicionales la secuencia: 123 , se interpreta según:
123 = 1*100 + 2*10 + 3
y también :
((1*10)+2)*10+3
Asumiremos que en la variable global ch, de tipo carácter, se encuentra el carácter que aún
no ha sido procesado. La constante b es la base, 10 en este caso.
procedure leaentero(var x:integer);
begin
while ch=' ' do read(ch); x:=0;
while esdigito(ch) do
begin
x:=x*b+valor(ch);
read(ch)
end
end;
Nótese que después de ejecutado leaentero, en ch queda el siguiente carácter, diferente de
un dígito. Esto se denomina lectura por adelantado (lookahead). Además, se descartan los
espacios antes de la secuencia de un entero. En caso de no corresponder a un entero, no
avanza en la secuencia de entrada y asigna valor cero al entero; esto obviamente es una
limitación.
Modificar el algoritmo para detectar errores en la entrada y para limitar, el largo de la
secuencia, al máximo entero representable; o bien, para detectar el rebalse y pedir reentrar el
entero.
Debe notarse que el procedimiento lee desde el archivo estándar de entrada; y debe
modificarse si se desea leer desde un archivo de texto externo.
También es preciso efectuar modificaciones si se desea leer números con signo.
Prof. Leopoldo Silva Bijit.
07-07-2003
309
UNIVERSIDAD TECNICA FEDERICO SANTA MARIA
DEPARTAMENTO DE ELECTRONICA
Programación en Pascal
Capítulo 26. Representación de números. Conversiones.
Con este primer ejemplo, debe destacarse la gran cantidad de detalles que quedan
abstraídos cuando se emplea la instrucción read con argumento entero.
26.4 Lectura de fracciones.
El siguiente procedimiento permite leer una fracción decimal. El número debe ser menor
que uno.
procedure leefraccion(var x:real);
var e : real;
begin
while (ch=' ') or (ch='0') do read(ch);
x:=0; e:=b;
if ch='.'
then
begin
read(ch);
while esdigito(ch) do
begin
x:=x+valor(ch)/e;
e:=b*e;
read(ch)
end
end
end;
No se detectan fracciones mal escritas. Debido a que el algoritmo trabaja con números
reales, existirá un error inherente en la conversión. Tampoco se limita el largo de la secuencia
de la fracción de entrada; si ésta es muy larga existirán errores por vaciamiento en la división.
El signo de la fracción no es considerado en el algoritmo.
Los procedimientos anteriores, al trabajar con números decimales, siguen siendo
abstracciones. Los procedimientos reales deben trabajar en aritmética binaria, y describirse
en instrucciones de más bajo nivel.
26.5. Lectura de reales punto fijo.
Puede diseñarse este procedimiento en términos de los anteriores.
Prof. Leopoldo Silva Bijit.
07-07-2003
310
UNIVERSIDAD TECNICA FEDERICO SANTA MARIA
DEPARTAMENTO DE ELECTRONICA
Programación en Pascal
Capítulo 26. Representación de números. Conversiones.
26.6. Escritura de enteros.
Asumiremos enteros de n cifras.
procedure escribaentero(x:integer);
var i : 1..n;
r : array [1..n] of char;
begin
for i:=n downto 1 do
begin
r[i]:=caracter(x mod b);
x:=x div b;
end;
for i:=1 to n do write(r[i])
end;
El procedimiento debe modificarse para considerar el signo y también si se desea suprimir
los ceros a la izquierda; en este caso debe usarse while en lugar de for.
También puede pasarse un parámetro con el ancho del número.
26.7. Escritura de fracción.
procedure escribafraccion(x:real);
var i : 0..n ;
v : integer;
begin
write('.'); i:=0;
repeat
x:=b*x; v:=trunc(u);
write(caracter(v));
u:=u-v; i:=i+1
until i=n
end;
El procedimiento no contempla signos, y tampoco el máximo representable. La
aproximación es por truncamiento; pero podría modificarse para aproximar por redondeo.
26.8. Cambio de base en números punto flotante.
Prof. Leopoldo Silva Bijit.
07-07-2003
311
UNIVERSIDAD TECNICA FEDERICO SANTA MARIA
DEPARTAMENTO DE ELECTRONICA
Programación en Pascal
Capítulo 26. Representación de números. Conversiones.
Una representación interna usual de números reales es en notación punto flotante en sistema
binario. Es decir, un número real r se representa por un par de números enteros tales que:
r = m * b^e
Donde m es la mantisa y e el exponente. La mantisa suele normalizarse, y es tal que:
1/b <= m < 1 ; donde b es la base.
Internamente la base suele ser una potencia de dos.
Si b = 2^k , un aumento o decremento en uno del exponente e, significa una multiplicación o
división de m por 2^k. Esto se implementa por un corrimiento de k bits a la izquierda y
derecha respectivamente.
Sin embargo, en forma externa, la base suele ser 10. Por esta razón, es necesario disponer
de procedimientos que conviertan un número punto flotante en una base dada en otra.
Explicaremos el algoritmo efectuando las operaciones en sistema decimal, para beneficio del
lector. Sin embargo, los procedimiento básicos para realizar estas operaciones deben
plantearse con operaciones en sistema binario, para las cuales existen instrucciones en el
repertorio de cualquier procesador.
Dado un número :
r = m1*b1^e1
Se desea obtener su representación equivalente en base b2:
r = m2*b2^e2
En la práctica, b1 y b2 son 10 y 2, y viceversa.
procedureconvierta(varm:real;e1:integer;var e2:integer);
begin
e2:=0;
if e1>=0
then
Prof. Leopoldo Silva Bijit.
07-07-2003
312
UNIVERSIDAD TECNICA FEDERICO SANTA MARIA
DEPARTAMENTO DE ELECTRONICA
Programación en Pascal
Capítulo 26. Representación de números. Conversiones.
while e1>0 do
begin
m:=b1*m; e1:=e1-1;
while m>=1 do
begin
m:=m/b2; e2:=e2+1
end
end
else
repeat
m:=m/b1; e1:=e1+1;
while m <(1/b2) do
begin
m:=m*b2; e2:=e2-1
end
until e1=0
end;
El algoritmo es ineficiente, pues el número de operaciones es proporcional a e; además es
inexacto debido a las aproximaciones de redondeo o truncamiento para mantener la mantisa
de un largo dado.
La esencia del algoritmo es alternar las multiplicaciones (o divisiones) de m por b1, con las
divisiones (o multiplicaciones) por b2, de tal forma que m se mantenga normalizada; o bien,
que se mantenga en el rango:
1/b <= m < b ; con b = b1*b2
Puede verificarse, a través del algoritmo que:
0.32*2^4 = 0.512*10^1
Nótese el diferente tratamiento para los números con exponente positivo y negativo.
26.9 Rutinas más reales de lectura y escritura.
En User Manual pág. 122 a 125 se encuentran procedimientos generales para leer y escribir
números reales. En ellos se mantienen los números reales dentro del rango de representación
interna del computador empleado. Se usan 48 bits para la mantisa y 11 bits para el
exponente, y 1 para el signo de la mantisa. El largo de la palabra es 60 bits.
Prof. Leopoldo Silva Bijit.
07-07-2003
313
UNIVERSIDAD TECNICA FEDERICO SANTA MARIA
DEPARTAMENTO DE ELECTRONICA
Programación en Pascal
Capítulo 26. Representación de números. Conversiones.
Se leen números de acuerdo a la sintaxis de números reales en Pascal.
En caso de vaciamiento se asigna cero al valor leído.
Existe una función que evalúa 10^e a través de operaciones primitivas de corrimiento en
sistema binario.
La rutina de escritura maneja el parámetro de escritura y también incorpora la idea de
redondeo para un número de cifras decimales dado.
En la parte de escritura aparecen algunos números mágicos. Se emplean en operaciones
enteras escaladas, en las que aparecen números reales aproximados a enteros. El factor de
escala empleado es el máximo entero del tipo que se esté usando.
El segmento que efectúa la conversió n de un entero a una secuencia de caracteres puede
simplificarse, efectuando divisiones enteras por 10, en lugar de aritmética entera escalada.
Los mismos programas, pero con algunos comentarios adicionales se encuentran en
Algorithms + Data Structures = Programs, págs. 45 a 49.
26.10 Abstracción de la Entrada/Salida.
Lo destacable de este capítulo es que un lenguaje de alto nivel oculta al programador los
detalles de conversión de números de representación interna a externa y viceversa.
Estudiando los programas planteados pueden observarse la complejidad de las operaciones
que son asumidas implícitamente cuando se emplean las sentencias read y write.
Prof. Leopoldo Silva Bijit.
07-07-2003
314
Descargar