• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

pedrotuga

Desafio - calculo do valor de pi

7 mensagens neste tópico

Ora, vai aqui um desafio mais simples então.

Titulo do Desafio

      - Cálculo do valor de PI

    Objectivo

      - Calcular o valor de PI utilizando apenas algebra cartesiana.

    Exemplo de Input/Output:

      - um valor aproximado de PI

    Material de Apoio

      - O problema resume-se a aproximar o valor de pi de forma arcaica ( é a única forma que exste ) A resolução consistirá em medir o comprimento de uma circunferencia e relaciona-la com o diametro desta.

    Restrições

      - O objectivo é recrear a descoberta do pi. A belaza deste número é forma como é um conceito simples mas muito particular. Pelo a simplicidade e o aparecimento do valor de pi assim vindo de um programa de computador é uma sensação engraçada. Para manter o problema 'divertido' só é permitido o recurso às quatro operações ariteméticas elementares ( + - * / ) e à exponeciação/radiciação.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Implementei isso com séries de taylor em scheme numa aula de programação..

(Acho que foi o Pi, o "e" é bastante mais fácil, mas agora não tenho a certeza)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Olás,

Este problema já parece estar para aqui cheio de bolor no fundo do forum.  :D

Mas passeava-me por aqui numa daquelas noites de insónias e "Deixa lá ver se encontro uma solução?"

E vai que nao vai, deparei-me com um Fenómeno interessante.  :hmm:

Usar operações elementares e raízes quadradas e exponenciação...

Vamos lá calcular o perimetro da circunferencia. Mas aquela coisa é redonda??

Aproximação por pequenas rectas...

Criar uma circunferencia num espaço cartesiano.

Equação da circunferência? X2+Y2=R2

Ou seja: isto é o conjunto de todos os pontos X e Y que estão à distancia R do centro do referencial (ou seja o Ponto com X = 0 e Y = 0)

Se eu dividir a circunferencia em 4 partes iguais basta-me calcular o perimetro de um quarto da circunferencia e multiplicar depois por  4, para ficar a saber o perimetro total.

Se sobre esse um quarto da circunferencia começar a medir a distancia entre muitos pontinhos que fiquem sobre a mesma, a soma, dá-me o perimetro dessa zona.

Explicação massuda à parte, aqui fica um algoritmo em vb2008.

2 valores de entrada: - Raio da circunferencia;

                                    - Numero de rectas pequenas para calculo do perimetro (quantas mais, mais preciso o valor do perimetro)

Sub Main()
        Dim r, x1, x2, y1, y2, soma, dist, NIntervalo As Double


        Console.Write("Qual o raio? ")
        r = Console.ReadLine()

        Console.Write("Qual o numero de Intervalos? ")
        NIntervalo = Console.ReadLine()
        NIntervalo = r / NIntervalo

        x1 = 0
        y1 = Math.Sqrt(r ^ 2 - x1 ^ 2)
        dist = 0
        soma = 0


        For x2 = NIntervalo To r Step NIntervalo
            y2 = Math.Sqrt(r ^ 2 - x2 ^ 2)

            dist = Math.Sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
            soma += dist
            x1 = x2
            y1 = y2


        Next

        soma *= 4

        Console.WriteLine()
        Console.WriteLine("Perimetro da circunferencia = " & soma)
        soma /= (2 * r)


        Console.WriteLine("PI Calculado = " & soma)
        Console.WriteLine("PI Definido =  " & Math.PI)
        Console.WriteLine()

        Console.WriteLine("('q' para terminar.)")
        If Console.ReadLine() = "q" Then End


        Console.ReadLine()

    End Sub

Depois de isto feito e corridos alguns exemplos... "Ai que maravilha.. parece estar a funcionar".

Todos os valores estavam proximos do 3,14 até que começaram a aparecer umas ovelhas negras à medida que aumentava o numero de rectas... depois desaparecia, continuava a aumentar o numero de rectas... e lá voltava a aparecer...

Acrescentei mais umas linhas de código e vá de fazer uma tabela, para o mesmo Raio de circunferência, fazendo apenas variar o numero de rectas para o calculo do perimetro.

Eis um excerto da tabela:

10 3,132264619
20 3,13830042
30 3,139801571
40 3,140429624
50 3,140760537
60 3,140959714
70 2,803028741
80 3,141181623
90 3,141248078
100 3,141298441
110 2,871657806
120 2,883170056
... ...

Construi uma tabela com valores progressivamente maiores de numeros de segmentos de recta para calcular o perimetro e o respectivo valor de Pi.

Fiz um gráfico com o resultado e, ei-lo aqui...  :)

valor+de+pi.JPG

Alguem me consegue propor uma explicação para esta alternância tão grande de valores para Pi à medida que o numero de iterações para o calculo do perimetro aumenta?? :eek:

Um bem haja,

Paulo Astro.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Porque x2 + NIntervalo às vezes ultrapassa o limite r antes do devido.

Nesses casos, em vez de contares N segmentos de recta contas N-1 e a soma dá-te menor.

Os números "floating point" têm dessas surpresas :)

Por exemplo, para raio=10 e 70 intervalos os x2 sucessivos são

0.142857

0.285714

0.428571

...

9.71429

9.85714

10.0000000000000000000000000000001897234

Edit

Este último devia ser

9.999999999999999999999923184046874

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Uma solução em python:

def PI(intervalo):
soma,x1,y1,x2,y2 = 0.,0.,1.,0.,1.
while 1:
	if x1 == 1.:
		print soma*2
		break
	x2 += intervalo
	if x2 >= 1.:
		x2,y2 = 1.,0.
	else:
		y2 = (1.-x2**2)**.5
	soma += ((x2-x1)**2+(y2-y1)**2)**.5
	x1,y1 = x2,y2

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Os números "floating point" têm dessas surpresas  :P

Por exemplo, para raio=10 e 70 intervalos os x2 sucessivos são

0.142857

0.285714

0.428571

...

9.71429

9.85714

10.0000000000000000000000000000001897234

Bem observado...  :P

O que faz com que seja preciso ter um cuidado redobrado com os números de virgula flutuante...

Parece-me que vou ter que fazer umas revisões sobre o assunto.

Obrigadinho,

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sempre que compararem números de vírgula flutuante, usem uma margem de tolerância para evitar precisamente isso.

Ou seja, neste caso, seria to r+Epsylon, onde epsylon será a vossa margem de tolerância, que pode ser pequena como por exemplo 10^-9.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora