MAC2166 - Introdução à Computação

03/06/2014 - Aula 17

Linguagem C - Problema 3

Dado um número inteiro n > 0, determinar o número harmônico Hn dado por

Hn = 1 + 1/2 + 1/3 + 1/4 + . . . + 1/n .

Imprima cada termo da sequência e o resultado final.

Você pode implementar da direita para a esquerda e da esquerda para direita. Qual dessas formas é estável?

Obs.: Este problema corresponde ao exercício 2 da lista de exercícios sobre reais.

Solução

In []:
#include <stdio.h>

int main()
{
    int n, x;
    float h_0aN, h_Na0;

    printf("Digite o numero n: ");
    scanf("%d", &n);

    /* Calcula a soma dos menores termos para os maiores */
    h_0aN = 0;
    for (x=1; x<=n; x++){
        h_0aN += (float) 1 / x;     /* ou  h_0aN += 1.0 / x; */
        printf("Termo %d: 1 / %d = %.10f   H(%d) = %.10f\n", x, x, 1.0/x, x, h_0aN);
    }

    /* Calcula a soma dos maiores termos para os menores */
    h_Na0 = 0;
    for (x=n; x>0; x--){
        h_Na0 += (float) 1 / x;     /* ou  h_Na0 += 1.0 / x; */
        printf("Termo %d: 1 / %d = %.10f   H(%d) = %.10f\n", x, x, 1.0/x, x, h_Na0);
    }

    printf("De 0 a N temos: %.30f\nDe N a 0 temos: %.30f\n", h_0aN, h_Na0);
    if (h_0aN == h_Na0)
        printf("Esses valores sao iguais!\n");
    else
        printf("Esses valores NAO sao iguais!\n");

    return 0;
}

Obs1.: Aos testar o programa para valores pequenos de n, os valores calculados para Hn "da esquerda para direita" e "da direita para esquerda" são equivalentes. Mas para valores de n maiores, os resultados calculados pelas duas estratégias se diferem.

Obs2.: A soma calculada dos menores termos para os maiores (H_Na0) é a solução mais estável, por envolver operações de soma entre números de valores mais próximos um do outro.

Linguagem C - Problema 4

  1. Dados números reais x > 0 e epsilon > 0, escreva uma função para calcular uma aproximação da raiz quadrada de x através da seguinte sequência:

r0 = x e

rn+1 = 1/2 (rn + x/rn).

Exemplos:

     Para x = 3, r0 = 3, r1 = 2,   r2 = 1.75, r3 = 1.732143, r4 = 1.732051
     Para x = 4, r0 = 4, r1 = 2.5, r2 = 2.05, r3 = 2.000610, r4 = 2.000000
     Para x = 5, r0 = 5, r1 = 3,   r2 = 2.33, r3 = 2.238095, r4 = 2.236068
     Para x=0.81, r0=0.81, r1=0.905, r2=0.9000138122, r3=0.9000000001
    

A aproximação será o primeiro valor rn+1 tal que |rn+1-rn| < epsilon.

  1. Escreva um programa que leia um real e imprima a sua raiz.

Você pode comparar o resultado com o sqrt do math.h .

Solução

In []:
#include <stdio.h>
#include <math.h>   /* Biblioteca que contem funcoes matematicas */

float raiz_quadrada(float x, float epsilon);

int main()
{
    float x, epsilon;

    printf("Digite o valor de x: ");
    scanf("%f", &x);
    printf("Digite o valor de epsilon: ");
    scanf("%f", &epsilon);

    printf("A aproximacao para a raiz quadrada de %f eh: %f\n", x, raiz_quadrada(x,epsilon));
    printf("A raiz quadrada de %f segundo a funcao sqrt da math.h eh: %f\n", x, sqrt(x));

    return 0;
}

float raiz_quadrada(float x, float epsilon){
    float r, r_ant, erro;

    r = r_ant = x;
    erro = epsilon;

    while (erro >= epsilon) {
        /* calcula o proximo elemento da sequencia */
        r = (r_ant + x / r_ant) / 2;

        /* calcula o erro relativo */
        if (r_ant != 0) {
            erro = (r - r_ant) / r_ant;

            if (erro < 0)
                erro *= -1;
        }
        else {
            if (r == 0)
                erro = 0;
            else
                erro = 1;
        }

        r_ant = r;
    }

    return r;
}

Problema 5

Dado um número real \(x\) e um número real \(epsilon > 0\), escreva uma função para calcular uma aproximação de \(e^x\) através da seguinte série infinita:

\[ e^x = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \ldots + \frac{x^k}{k!} + \ldots\]

Inclua na aproximação todos os termos até o primeiro de valor absoluto (módulo) menor do que \(epsilon\).

In []:
#include <stdio.h>
#include <math.h>

#define SOL2 0 /* Constante que deve valer 1 quando deseja-se usar a solucao 2; 0 em caso contrario */

float exponenciacao(float x, float eps);

int main(){
    float x, eps;

    printf("Digite x: ");
    scanf("%f", &x);
    printf("Digite epsilon: ");
    scanf("%f", &eps);

    printf("e^(%5.3f) = %7.4f", x, exponenciacao(x,eps));

    return 0;
}

float exponenciacao(float x, float eps){
    float termo, soma;
    int k, fat;

    termo = 1;
    soma  = 1;
    k = 0;

    if (SOL2){
        /* Solucao 1 */
        fat = 1;
        while (termo >= eps || -termo >= eps) {
            k+=1;
            fat *= k;
            termo = pow(x,k) / fat;
            soma += termo;
        }

    }
    else
        /* Solucao 2 */
        while (termo >= eps || -termo >= eps){
            k += 1;
            termo = x * termo / k;
            soma += termo;
        }

    return soma;
}

Problema 6

Dados \(x\) real e \(n\) natural, escreva uma função para calcular uma aproximação para \(cos\ x\) através dos \(n\) primeiros termos da seguinte série:

\[cos(x) = 1 - \frac{x^2}{2!} + \frac{x^4}{4!} - \frac{x^6}{6!} + \ldots + (-1)^k \frac{x^2k}{2k!} + \ldots \]

Compare com os resultados de sua calculadora!

Obs.: Esse problema é o exercício 6 da lista de exercícios sobre reais.

In []:
#include <stdio.h>

float cosseno(float x, int n);

int main()
{
    float x;
    int n;

    printf("Digite o valor de x: ");
    scanf("%f", &x);

    printf("Digite o valor de n: ");
    scanf("%d", &n);


    printf("O valor aproximado para o cos %f eh: %f", x, cosseno(x,n));

    return 0;
}

float cosseno(float x, int n){
    float cos, t;
    int k;

    cos = t = 1.0;

    for (k = 1; k < n; k++) {
        t = -1 * t * x*x / ((2*k - 1) * 2*k);
        cos += t;
    }

    return cos;
}

Tópicos vistos na Aula 17

Referências e outros materiais para estudo