TAREA 2 Ejercicios 1. Considera el siguiente algoritmo, muy

Transcripción

TAREA 2 Ejercicios 1. Considera el siguiente algoritmo, muy
TAREA 2
Ejercicios
1. Considera el siguiente algoritmo, muy empleado para calcular iterativamente la raı́z
cuadrada de un número z real y positivo:
Se toma un valor inicial arbitrario, z0 .
Dada una solución zn , se obtiene otra mejor, zn+1 , ası́:
z
1
zn+1 = (zn + )
2
zn
(1)
Se itera (1) mientras |zn − zn+1 | > ǫ, para ǫ muy pequeñito1
Responde a las siguientes cuestiones:
a) Examina la expresión (1) y explica porqué converge a la raı́z buscada. No es
precisa una demostración formal y rigurosa: basta iterar a mano unas pocas
veces y te darás cuenta de la convergencia; explica a continuación la razón.
b) Escribe un programa en C que calcule e imprima una tabla con las raices
cuadradas de los cien primeros números naturales, z = 1, ..., 100.
c) ¿Qué papel juega ǫ en cada iteración? ¿ Qué ocurre al aumentarlo o disminuirlo?.
2. En la cuestión anterior has escrito un programa que calculaba e imprimı́a las raices
cuadradas de los cien primeros números naturales. Aprovechando el trabajo hecho,
escribe lo mismo haciendo uso de una función raizcuad() cuyo argumento sea int y
devuelva como resultado una variable tipo float.
3. Examina el siguiente programa:
#include <stdio.h>
#define N 3
int c=0;
int a[N] = {4,4,4};
void incrementa (int c, int a[]){
int i;
for(i=0; i<N; i++){
a[i]+=3;
}
c+=3;
printf("Dentro, c=%d y a=%d %d %d\n",
c, a[0], a[1], a[2]) ;
}
main() {
printf("Antes, c=%d y a=%d %d %d\n",
1
Esta descripción es una simplificación del algoritmo. Al responder a las cuestiones te será evidente la
razón.
1
c, a[0], a[1], a[2] );
incrementa(c,a);
printf("Despues, c=%d y a=%d %d %d\n",
c, a[0], a[1], a[2]) ;
}
Explica cuál es el resultado de las tres sentencias printf() y explica la razón. Puedes
si lo deseas ejecutarlo.
4. Supón una calculadora que admitiera números de hasta cinco cifras significativas.
¿Qué ocurrirı́a al sumar dos números como 1.0003 y 0.0000085?
P
Definamos Sn = nk=1 k−2 . A la vista de tu respuesta anterior ¿ Qué algoritmo de los
dos a continuación utilizarı́as para calcular S10000000 en un ordenador con números
de ocho dı́gitos decimales significativos? ¿Por qué?
k←1
Sn ← 0
while k < 10000000 do
Sn ← Sn + k−2
k ←k+1
end while
k ← 10000000
Sn ← 0
while k > 0 do
Sn ← Sn + k−2
k ← k−1
end while
Ayudas, comentarios,...
1. Al definir la función raizcuad() en el ejercicio 2 lo harás ası́:
float raizcuad(int n){
....
}
En C no ANSI se empleaba:
float raizcuad(n)
int n;
{
....
}
El declarar el tipo de variable en la lista de argumentos de la función hace el programa
más legible y simplifica el trabajo del compilador. Si intentas compilar la primera
forma sin especificar la opción -Aa, obtendrás un mensaje de error.
2. Una cuestión tangencial relativa al ejercicio 4: cuando n → ∞, |Sn+1 − Sn | → 0.
P
−2 sumando hasta que dos términos
Si uno quisiera aproximar el valor de ∞
k=1 k
sucesivos fuesen muy similares, no habrá nada que objetar.2
Pero observa que la regla ”parar cuando dos términos sucesivos se paracen mucho”, puede ser desastrosa. Por ejemplo, si en lugar de la serie considerada, tuvieras
2
Salvo que: a) Es perfectamente innecesario, la serie citada tiene valor conocido y obtenible teóricamente
( π6 ), y b) El error serı́a no la diferencia |Sn+1 − Sn | sino la suma de los términos despreciados.
2
P∞
el valor de cada sumando, k−1 , y por lo tanto la diferencia entre dos sumas sucesivas, convergerı́a hacia cero. Sin embargo, la serie es divergente, hacia ∞
(es la llamada armónica natural) y el aproximarla por cualquier suma parcial Sn ¡da
un error infinito!
k=1 k
−1 ,
Ahora que ya lo sabes hacer...
...no es preciso que lo hagas nunca más.
1. No es preciso que guardes la función raizcuad() que has escrito en el problema 2. Hay
una función standard en C para computar la raı́z cuadrada: sqrt(). Para utilizarla
basta incluir en tu programa una lı́nea como
#include < math.h >
y compilar utilizando la biblioteca de funciones matemáticas ( lo que supone invocar
la opción -lM). Tienes además disponibles las funciones matemáticas más usuales,
con los nombres esperables: sin, cos, log, exp, etc. Puedes ver una descripción de
dicha biblioteca en [?].
Referencias
[1] Hewlett-Packard, HP C/HP-UX Reference Maunal. HP 9000 Series 600/700/800
Computers, Hewlett- Packard Co., Cupertino, Ca., 1991.
3