Sie sind auf Seite 1von 8

Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.

html

Computación Numérica

Profesores: José M. Alonso, Fernando Alvarruiz, Juan Garayoa, Jesús Peinado, José L. Pérez, José E.
Román, Vicente Vidal.
http://www.dsic.upv.es/asignaturas/eui/cnu/prac

Práctica 3 - Errores en la Aritmética de Coma Flotante


Como se ha estudiado en teoría, en Computación Numérica existen diferentes fuentes
de errores. En esta práctica vamos a estudiar una de ellas: los errores de redondeo,
debidos a que en el ordenador se realizan los cálculos con los números representados
en un formato de precisión finita (es decir, sólo es posible almacenar un número de
dígitos limitado).

La práctica consta de los siguientes apartados:

1. Errores con pocos dígitos de precisión


2. Representación en formato IEEE-754
3. Errores en el formato IEEE-754
4. Valores característicos del formato IEEE-754 (opcional)

3.1. Errores con pocos dígitos de precisión


En este apartado vamos a abordar un problema muy sencillo (la ecuación de segundo grado),
planteando la resolución de diferentes formas y viendo en cada caso cuál es el error que se ha
cometido.

Objetivos evaluables:

Observar que el error depende del número de dígitos utilizados para


representar los números.
Saber obtener errores absolutos y relativos, y analizar sus valores.
Saber identificar situaciones en las que se produce cancelación de
dígitos significativos, y el efecto que esto tiene en el error.
Saber realizar programas sencillos en Matlab.

Funciones auxiliares
Como veremos en el próximo apartado, Matlab representa los números con unos 16 dígitos de
precisión. Sin embargo, en este apartado vamos a trabajar con menos dígitos, para que la aparición
de errores sea más evidente. Para ello, vamos a utilizar unas funciones que simulan las operaciones
aritméticas elementales, utilizando tantos dígitos como queramos (menos de 16). Las cabeceras de las
funciones son:

function x=suma_r(a,b,n)
% x=suma_r(a,b,n) devuelve la suma de a y b, realizada con n dígitos

1 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html

% decimales de precisión

function x=resta_r(a,b,n)
% x=resta_r(a,b,n) devuelve la resta a - b, realizada con n dígitos
% decimales de precisión

function x=prod_r(a,b,n)
% x=prod_r(a,b,n) devuelve el producto de a y b, realizado con n dígitos
% decimales de precisión

function x=div_r(a,b,n)
% x=div_r(a,b,n) devuelve la división a / b, realizada con n digitos
% decimales de precisión

function x=exp_r(a,b,n)
% x=exp_r(a,b,n) devuelve "a" elevado a "b", realizado con n dígitos
% decimales de precisión; atención, sólo funciona para b entero mayor
% o igual que 0

function x=redond(a,n)
% x=redond(a,n) devuelve en x el valor "a" redondeado a n dígitos
% decimales de precisión

La ecuación de segundo grado

Las raíces de la ecuación de segundo grado ax2+bx+c=0 se pueden calcular mediante las
expresiones

Una función implementada en Matlab que calcule las dos raíces utilizando estas expresiones podría
ser la siguiente:

function [x1,x2] = raices1(a,b,c,n)


% Calcula las dos raices de la ecuacion de segundo grado ax2+bx+c=0,
% realizando las operaciones con n digitos de precision.

y = prod_r(b,b,n); % calcula el cuadrado de b


z = prod_r(4,prod_r(a,c,n),n); % calcula 4ac
d = resta_r(y,z,n); % calcula el discriminante
s = redond(sqrt(d),n); % calcula la raiz
x1 = div_r(suma_r(-b,s,n),prod_r(2,a,n),n); % x1 = (-b+s)/(2*a)
x2 = ... COMPLETAR ...

Ejercicio 1: Completa la función anterior y utilízala para resolver una cierta ecuación (valores de a, b,
c fijos) variando los valores de n (por ejemplo, entre 1 y 16). Observa que para diferentes
precisiones (valores de n) los resultados varían. La lógica nos hace pensar que los resultados más
cercanos al valor correcto se obtienen en el caso en que más dígitos de precisión se utilizan. Sin
embargo, no conviene fiarse de la lógica: vamos a analizar el error cometido en cada caso.

Cálculo del error cometido


A continuación vamos a calcular el error relativo en los resultados obtenidos. En la solución x1 el

2 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html

error relativo será , donde x1 es el valor de la solución exacta y de la solución


aproximada, y de manera similar en la solución x2. Por tanto, para calcular el error necesitamos
conocer el valor exacto de las soluciones.

Podemos asumir que las soluciones exactas de la ecuación son las que calcula Matlab con la función
roots. Esta función calcula las raíces de un polinomio p(x)=anxn+...+a2x2+a1x+a0, el cual se
representa en Matlab mediante un vector fila [an ... a1 a0]. Por ejemplo, para la ecuación
x2+111.11x+1.2121=0

>> p = [ 1 111.11 1.2121 ];


>> x = roots(p);
>> x(1)

ans =

-111.0991

>> x(2)

ans =

-0.0109

>>

Ejercicio 2: Realizar un script de Matlab que mediante un bucle variando n desde 1 hasta 16 calcule
las raíces de la ecuación usando la función raices1, obtenga las soluciones exactas mediante roots y
calcule el error relativo de cada una de las soluciones, tanto x1 como x2. El script debe mostrar el
valor de n y los errores. Realiza el análisis de los errores con la siguiente ecuación: x2+62.1x+1=0.
En particular, observa:

¿Cómo varía el error al aumentar el número de dígitos de precisión?


¿Presentan las 2 raíces un error similar? Si no es así, ¿a qué es debida la diferencia de error?

Nota: En el ejercicio anterior, para poder calcular el error, las soluciones obtenidas con raices1 y con
roots deben estar en el mismo orden. Para ello, puede ser necesario utilizar la función sort de
Matlab.

Fórmulas alternativas

Una alternativa para calcular las raíces de la ecuación de segundo grado ax2+bx+c=0 es racionalizar
las expresiones anteriores, con lo que se obtienen estas nuevas fórmulas

Ejercicio 3: Implementa una función Matlab raices2, similar a raices1, que utilice estas expresiones.
Repite el análisis de errores con esta nueva función. A la vista de los resultados, ¿cuáles crees que
son la expresiones que menor error comenten? ¿Crees que en algún caso se está produciendo un
fenómeno de cancelación de dígitos?

3 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html

3.2. Representación en Formato IEEE-754


En este apartado vamos a trabajar con la representación de los números en coma flotante que utiliza
Matlab, que no es otra que el formato de doble precisión del IEEE-754.

Objetivos evaluables:

Comprender bien el formato de representación de números en coma


flotante IEEE-754.
Saber explicar lo que ocurre en algunas operaciones aritméticas cuyo
resultado puede parecer extraño.

El formato IEEE de doble precisión


El formato IEEE de números en coma flotante de doble precisión es una palabra de 64 bits dividida
en: un indicador de signo s de 1 bit, un exponente e de 11 bits, y una parte fraccionaria f de la
mantisa de 52 bits. Una representación de este formato sería la siguiente:

La relación entre este formato y la representación de números reales viene dada por la siguiente
expresión, que pone el valor del número v en función del contenido de los tres campos s, e, f.

Matlab utiliza siempre este formato para representar los números internamente. Ahora bien, a la hora
de mostrar los números por la pantalla, Matlab lo hace con un cierto número de dígitos decimales. La
forma de mostrar los números se puede cambiar, como se muestra en el siguiente ejemplo:

>> pi

ans =

3.1416

>> format long


>> pi

ans =

3.14159265358979

En esta práctica, nos interesa estudiar en detalle cómo se representan los números internamente y,
por ello, queremos mostrar el formato de 64 bits completo, tal como se almacena en binario. Para
ello, podemos utilizar la función destripa (nota: esta función no forma parte de Matlab).

4 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html

>> destripa(pi)

---> volcado binario: dumpb(3.141592653589793)

s exponente.. mantisa............................................. n
0 10000000000 1001001000011111101101010100010001000010110100011000 <3.141592653589793>

---> volcado hexadecimal: dump(3.141592653589793)


s+e mantisa...... mantisa.......... exp.. n
400 921fb54442d18 ==> 1.570796326794896*2^1 <3.141592653589793>

... exp~=min y exp~=max ==> número normalizado


exp:0x400 (=1024) ==> exponente=(1024-1023)=1

Ejercicio 4: Utiliza la función destripa para analizar la representación de varios números. En


particular, comprueba la representación de casos especiales del estándar IEEE, como el cero, infinito,
o algún número denormalizado como pueda ser 10-315.

Ejercicio 5: Utiliza la función destripa para analizar la representación de los números 1 y 2. ¿Por qué
la mantisa en binario aparece llena de ceros? ¿Por qué el exponente está a unos en un caso y a ceros
en el otro? Ahora, en base a la representación del 1 y el 2, piensa cuál sería el resultado de realizar la
suma (1+2=3). Piensa qué pasos realiza el procesador (igualar exponentes, sumar mantisas y
normalizar). Luego, utiliza destripa para comprobarlo.

Ejercicio 6: Realiza en Matlab las siguientes operaciones: 1+10-15 y 1+10-16. A primera vista, estas
operaciones son muy parecidas pero hay una diferencia importante. Utiliza destripa para ver la
representación del resultado en los dos casos. En el segundo caso, ¿qué diferencia hay con la
representación del 1? ¿Qué ha pasado?

3.3. Errores en el Formato IEEE-754


En el primer apartado observamos cómo se producen errores cuando se realizan operaciones con
pocos dígitos de precisión. En este apartado, vamos a ver que al trabajar con el formato IEEE de
doble precisión también se producen errores, a pesar de que contamos con 16 dígitos decimales de
precisión (53 dígitos binarios).

Objetivos evaluables:

Saber identificar situaciones en las que se produce cancelación de


dígitos significativos, y el efecto que esto tiene en el error.
Observar el efecto producido por la cancelación de dígitos
significativos.
Saber realizar programas sencillos en Matlab.

Aproximación de la derivada de una función en un punto


En este apartado vamos a calcular con Matlab un valor aproximado de la derivada de una función en
un punto. En principio, nos centraremos en un caso particular:

5 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html

Queremos calcular la derivada en el punto x0 = 2. El valor exacto de la derivada sería f '(2) = -0.25.
Ahora bien, vamos a calcular una aproximación de este valor como cociente de dos incrementos (de
manera similar a como se hizo en el ejemplo del paracaidista):

Ejercicio 7: Calcula la aproximación de la derivada en el punto x0 = 2 mediante la expresión anterior


para h = 0.01. Calcula el error relativo cometido.

Nota: Para estos ejercicios puede ser útil implementar la función f como una función de Matlab, en
un fichero f.m:
function v = f(x)
v = 1/x;

Error en el cálculo de la derivada


La derivada de una función en un punto es el límite de la expresión anterior cuando h tiende a 0. Por
tanto, parece lógico pensar que la aproximación calculada será mejor cuanto más pequeño sea el
valor de h utilizado. Sin embargo, esto en la práctica no es así, como veremos a continuación.

Ejercicio 8: Realiza un script de Matlab que mediante un bucle vaya decrementando el valor de h
desde 0.1 hasta 10-16 y, para cada uno de estos valores, calcule la aproximación de la derivada y el
error relativo cometido (en valor absoluto).

for i=1:16
h(i) = 10^-i;
der(i) = ... COMPLETAR
err(i) = ... COMPLETAR
end

Ejercicio 9: Modifica el script anterior para que realice una gráfica del error relativo en función de h.
Para que se aprecie mejor la variación del error, haz la gráfica con el comando loglog, que es
equivalente a plot pero utilizando escalas logarítmicas tanto en vertical como en horizontal. ¿A qué
se debe el comportamiento del error? ¿Cuál es el valor óptimo de h en este caso?

Ejercicio 10 (opcional): Repite el estudio para otros valores de x0 y otras funciones f.

3.4. Valores Característicos del Formato IEEE-754


(opcional)
Anteriormente hemos visto el formato IEEE de doble precisión. Con esta representación, ¿cuál es el
mínimo número representable? ¿Y el máximo? ¿Cuál es el menor número que sumado a 1 da un
resultado mayor que 1? En este apartado abordamos estas cuestiones.

6 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html

Objetivos:

Trabajar los conceptos de máximo y mínimo número representable, y


épsilon de la máquina.
Idear algoritmos que permitan calcular los valores característicos de
una máquina, como son el épsilon o la precisión.

Épsilon de la máquina (ε)

Hemos visto que en el formato IEEE doble precisión, la operación 1+10-15 da un resultado distinto
de 1, mientras que 1+10-16 da como resultado 1, es decir, el número 10-16 es tan pequeño que al
realizar la operación de suma se pierden todos los dígitos que pudiera aportar al resultado.

Como se ha visto en teoría, hay un valor que llamamos épsilon, ε, que es el mínimo número que
sumado a 1 da como resultado un valor mayor que 1. En el caso de IEEE doble precisión, este
número estará entre 10-16 y 10-15, como se ha visto por el ejemplo. Pero, ¿cuál es exactamente ese
valor?

El valor de ε se puede deducir de forma teórica a partir de la descripción del formato IEEE. Sin
embargo, lo que vamos a hacer ahora es obtenerlo mediante un algoritmo. La idea es realizar un
bucle en el cual probamos la operación 1+x para valores cada vez más pequeños de x, hasta detectar
que el resultado de la suma da exactamente 1.

function [x,n] = epsilon


% Devuelve en x el valor del epsilon de la maquina y en n el numero
% de bits de la mantisa.

n = 0;
x = 1;
y = 2;
while y~=1
fprintf('n=%g, x=%g, y=%g\n',n,x,y)
n = n+1;
x = x/2;
y = 1+x;
end
x = x*2;
n = n-1;

Nota: Observar que después del bucle se deshace la última iteración para recuperar el valor anterior
al que provocó la salida del bucle.

Otros valores característicos


Dada la siguiente función de Matlab
function [y,n] = quehace

n = 0;
x = 1;
y = 0;

7 de 8 16/3/06 17:53
Computación Numérica - Prácticas http://www.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.html

while x~=0
fprintf('n=%g, x=%g\n',n,x)
n = n+1;
y = x;
x = x/2;
end
n = n-1;

Ejercicio 11: Explica qué cálculo realiza la función. ¿Para qué sirve la asignación y = x?

Ejercicio 12: Realiza una función similar que obtenga el número máximo que puede representar
Matlab (por supuesto, sin considerar Inf). Esta función presenta una dificultad añadida que deberás
tener en cuenta (para saber a qué nos referimos, piensa cómo escribirías a mano el máximo
representable).

Ejercicio 13: Utiliza la función destripa para justificar que los valores obtenidos se ajustan al
formato de representación IEEE doble precisión.

Ejercicio 14: Compara los valores obtenidos con los que proporciona Matlab con los comandos eps,
realmin y realmax. ¿Coinciden en todos los casos? En el caso de que no sea así, justifica a qué se
debe la diferencia.

8 de 8 16/3/06 17:53

Das könnte Ihnen auch gefallen