PI z dokladnoscia

0

Liczbe nalezy obliczyc z nastepujacego wzoru :
user image

Ilosc iteracji powinna byc okreslana na podstawie zadanej dokladnosci.

moj program :

	{
			cout<<"podaj dokladnosc";
			double suma=0, w=10, dokl;
				cin>>n;
			for(int k=0; fabs(w)>dokl; k++)
			{
				
				suma=suma+(4*pow(-1.0,n))/(2*n+1);
				cout<<"PI:"<<suma;
				_getch();
			
			break;
			}}

Prosze o sprawdzenie i ewentualna poprawe.

0

Kolejny co optymalnośc ma gdzieś. Jaki sens wywoływac kosztowne pow() cały czas skoro
następyn wyraz szeregu = poprzedni wyraz szeregu *(-1)/(2k+1)
Uwierz mi że takie mnożenie jest kolosalnie mniej kosztowne niż pow() dla duzej potęgi...

0

tylko cos mi nie dziala , jak twoim zdaniem powiniem wygladac moj kod przy twojej tezie ?

0

Gafę tam walnąłem ;) Bo trzeba jeszcze pomnożyć przez poprzedni mianownik ;)

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
  double suma=1, wyraz=1, dokl; //suma =1 bo wyłączam zerowy wyraz dla ułatwienia
  cout<<"podaj dokladnosc"<<endl;
  int k=1; //bo zerowy wyraz dodałem do sumy
  cin>>dokl;
  while (abs(wyraz)>dokl)
    {
      wyraz*=(2*(k-1)+1); //wracamy do mianownika poprzedniego wyrazu
      wyraz=-wyraz; //zmieniamy znak
      wyraz/=(2.0*k+1); //dzielimy przez mianownik nowego wyrazu
      k++;
      suma+=wyraz; //sumujemy
    }
  cout<<"PI:"<<4*suma; //suma jest 4x większa
  return EXIT_SUCCESS;
}

0

hm wywala blad przy while , kompilowales u siebie ?

0

juz jest ok , tylko obiojetnie jaka wpisze liczbe wynik mam 4

0

Odpowiedź już dostałeś na gg, dokładność to jest na przykład 0.0001

0

Shalom źle piszesz. Liczenie tego szeregu przez mnożenie razy poprzedni wyraz jest głupie. Należy rozwinąć pętlę, tzn w jednym while'u liczyć dwa kolejne składniki, widzimy, że jeden będzie dodatni, a drugi ujemny, pozbywamy się całkowicie potęgi. Sprawa jest bardzo prosta.

Aby zwiększyć dokładność obliczeń, należałoby zawsze dodawać elementy o najmniejszej wartości bezwzględnej. Myślę, że dla autora ta technika byłaby za trudna i wystarczy zastosować prostszy, ale nieprecyzyjny trik, mianowicie sumować liczby od "końca" szeregu.

0

Do kodu powyżej powinno się dodać ustawianie precyzji przed wyświetlaniem wyniku.

cout.precision(10);
0

donkey7 mozesz napisac swoj kod bo teraz juz nie wiem jak powinna wygladac prawidlowa forma.

0

Hah zalogowało mnie z powrotem.

Podam kodzik bez rozwijania:

/* 
 * File:   main.c
 * Author: piotrek
 *
 * Created on 22 październik 2009, 00:22
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * 
 */
int main(int argc, char** argv) {

    float suma, dokladnosc;
    int iteracji;

    printf("Podaj dokładność: ");
    scanf("%f", &dokladnosc);

    iteracji = 1.0 / dokladnosc; // w rzeczywistości chyba wystarczy mniej o ile dobrze sumujemy
    suma = 0;

    while (iteracji >= 0) {

        if (iteracji % 2 == 0) {
            suma += 4.0 / (iteracji * 2 + 1);
        } else {
            suma -= 4.0 / (iteracji * 2 + 1);
        }

        iteracji--;

    }

    printf("Liczba PI wynosi: %f\n", suma);

    return (EXIT_SUCCESS);
}

0

ma ktos jeszcze jakas inna koncepcje bo nie wiem czy to jest dobrze ?

0
double calculatePi(double accuracy) {
     double sum = 0;
     unsigned int i=2.0/accuracy;
     i|=3; // enforce i%4=3
     do {
          sum -= 1.0/i;
          i-=2;
          sum += 1.0/i;
          i-=2;
     } while(i>0);
     return suma*4.0;
}
0

MarekR22:
Rozwinąłeś tylko pętlę ;)

0

ale pozbyłem się tego strasznego i%2, jednego mnożenia i dodawania na każde wykonanie pętli.
W sumie poprawiając po kawałku nie zauważyłem, że można to ładnie skrócić /poprawić (patrz wyżej).
Poza tym sumując od najmniejszych do największych poprawia się dokładność obliczeń.

1 użytkowników online, w tym zalogowanych: 0, gości: 1