Método da bissecção

Publicado por Renan Birck Pinheiro (última atualização em 03/11/2017)

[ Hits: 50.815 ]

Homepage: http://renanbirck.rocks

Download Bisseccao.c

Download programa 1.c (versão 2)




Implementação do método da bissecção para encontrar os zeros de uma função f(x). Novamente, não pretendo entrar em detalhes sobre o método, recomendo o uso de um livro de Cálculo Numérico para este fim.

f(x) é a função cujo zero queremos determinar.

Compilar usando o parâmetro -lm do GCC pois usamos funções matemáticas.

  



Versões atualizadas deste script

Versão 2 - Enviado por Eduardo Gomes Silva Junior em 29/10/2017

Changelog: Método da Bisseção em C.

Download programa 1.c


Esconder código-fonte

#include <stdio.h>
#include <math.h>

#define log10(x) log(x)/log(10);

float f(float x) {
   return pow(x,2)-4; // Função cuja raiz deve ser determinada
}

// Implementação do Método da Bissecção para zeros de funções
// Autor: Renan Birck
// Disciplina: Métodos Numéricos e Computacionais
// Curso: Eng. Elétrica - Universidade Federal de Santa Maria
// Santa Maria, maio de 2010.

int main() {
   
   // eps: erro
   // a0 e b0: pontos iniciais
   // tam: tamanho do intervlao
   // pm: ponto médio
   // it: número de iterações
   
   float eps, a0, b0, tam, pm, it; 
   int bolzano_ok = 0; // flag do teorema de Bolzano
   
   printf("Digite a precisão requerida: \n");
   scanf("%f",&eps);

   printf("Digite o intervalo onde deve se buscar a raiz (ex. [0;5] = digite 0 5): \n");
   scanf("%f %f",&a0,&b0);

   // O teorema de Bolzano (valor intermediário) foi satisfeito? 
   // f(a0) * f(b0) < 0 -> existe troca de sinal no intervalo dado e, portanto
   // existe raiz nele.
    bolzano_ok = (f(a0)*f(b0) > 0?0:1);

   // Não, então pedir um novo intervalo inicial.
   while(bolzano_ok == 0) {
      printf("\nIntervalo [%f;%f] não satisfaz as condições do teorema de Bolzano. Tente outro.\n Intervalo: ",a0,b0);
      scanf("%f %f", &a0, &b0);
      bolzano_ok = (f(a0)*f(b0) > 0?0:1);
   }

   // Iteraçõs necessárias

   it = log10(b0 - a0);
   it -= log10(eps);
   it /= log(2);

   printf("Serão necessárias %.0f iterações.\n",ceil(it));

   // Um dos extremos do intervalo é a raiz
   if(f(a0) == 0 || f(b0) == 0)  {
      printf("O valor %f é zero da expressão. \n", f(a0)==0?a0:b0);
      return 0;
   }

   // Implementação do método da bisecção


   while(tam > eps) {
      tam = b0-a0;
      pm = (a0+b0)/2;
      if(f(pm) == 0) {
         printf("SOLUÇÃO EXATA ENCONTRADA!! x = %f\n",pm);   
         return 0;
      }

      if(f(a0)*f(pm) < 0)  b0 = pm; // a solução está a esquerda
       else a0 = pm;  // a solução está a direita
      
   }
   
   printf("Intervalo final: [%f,%f]\n Solução aproximada: %f",a0,b0,(a0+b0)/2);

   return 0;
}

Scripts recomendados

Vários pacotes de ping disparados contra o host

Calcular dia da semana a partir de uma data sugerida

Conhecendo atributos do Ncurses

Um pouco de fisica

Ler N números e ver qual é o maior


  

Comentários
[1] Comentário enviado por azaiats em 18/08/2011 - 10:59h

Que lembrança isso me traz das lições de casa que tinha que fazer da PUC-SP... bons tempos de ciências da computação...

[]s

[2] Comentário enviado por lucassleopoldo em 11/12/2017 - 01:44h

Olá,

Gostei muito do seu programa, realmente me ajudou bastante.

Eu fiz algumas alterações no código para que eu pudesse utilizar de forma mais cômoda.

Segue o código com minhas alterações:

#include <stdio.h>
#include <math.h>

#define log10(x) log(x)/log(10);

float f(float x) {
return pow(x,2)-4; // Função cuja raiz deve ser determinada
}

// Autor: Renan Birck
// Disciplina: Métodos Numéricos e Computacionais
// Curso: Eng. Elétrica - Universidade Federal de Santa Maria
// Santa Maria, maio de 2010.

int main() {

// eps: erro
// a0 e b0: pontos iniciais
// tam: tamanho do intervlao
// pm: ponto médio
// it: número de iterações

float eps, a0, b0, tam, pm, it;
int i=0, bolzano_ok = 0; // flag do teorema de Bolzano

printf("Digite a precisao requerida: \n");
scanf("%f",&eps);

printf("Digite o intervalo onde deve se buscar a raiz (ex. [0;5] = digite 0 5): \n");
scanf("%f %f",&a0,&b0);

// O teorema de Bolzano (valor intermediário) foi satisfeito?
// f(a0) * f(b0) < 0 -> existe troca de sinal no intervalo dado e, portanto
// existe raiz nele.
bolzano_ok = (f(a0)*f(b0) > 0?0:1);

// Não, então pedir um novo intervalo inicial.

while(bolzano_ok == 0) {
printf("\nIntervalo [%f;%f] nao satisfaz as condicoes do teorema de Bolzano. Tente outro.\n Intervalo: ",a0,b0);
scanf("%f %f", &a0, &b0);
bolzano_ok = (f(a0)*f(b0) > 0?0:1);
}

// Iteraçõs necessárias

it = log10(b0 - a0)-log10(eps);
it -= log10(eps);
it /= log10(2);

printf("Serao necessarias %.0f iteracoes\n\n",ceil(it));

// Um dos extremos do intervalo é a raiz
if(f(a0) == 0 || f(b0) == 0) {
printf("O valor %f é zero da expressao. \n", f(a0)==0?a0:b0);
return 0;
}

// Implementação do método da bisecção

tam = b0- a0;

while(tam > eps) {
tam = b0-a0;
pm = (a0+b0)/2;

if(f(pm) == 0) {
printf("SOLUÇÃO EXATA ENCONTRADA!! x = %f\n",pm);
return 0;
}
printf ("Iteracao: %d | a= %f | b= %f | xi= %f | f(a)= %f | f(xi)= %f | Erro= %f\n",i,a0,b0,pm,f(a0),f(pm),b0-a0);
if(f(a0)*f(pm) < 0)
b0 = pm; // a solução está a esquerda

else
a0 = pm; // a solução está a direita

i++;
}

printf("\nSolucao aproximada: %f",pm);

return 0;
}


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts