Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][C++] POMOC przy przerabianiu kodu :)
Forum PHP.pl > Forum > Przedszkole
wert1
Witajcie, mam kod w c++ który ma obliczać liczbe PI do ilustam miejsc po przecinku smile.gif
CODE
#include <iostream>

using namespace std;

int main() {
long mianownik = 1;
long znak = 1;
double pi_4 = 0;

long i = 1000000000;

while (i--) {
pi_4 += static_cast<double>(znak) *
1.0 / static_cast<double>(mianownik);

mianownik += 2;
znak = -znak;
}

double pi = 4.0 * pi_4;

cout.precision(10);
cout << pi << endl;

system("pause");
}


Czy ktoś mogł by mi to przerobić na PHP ?
Darti
Tłumaczenie wprost:
  1. <?php
  2. function main(){
  3.  
  4. $mianownik = 1;
  5. $znak = 1;
  6. $pi_4 = 0;
  7. $i = 1000000000;
  8.  
  9. }
  10. ?>


tyle że to mało znaczy i nic w zasadzie nie robi ... (a zwłaszcza nie liczy pi)
wookieb
Zobacz ze kod jest w codebox co oznacza ze masz scrolla.
MolTAR
  1. <?php
  2.  
  3. $mianownik = 1;
  4. $znak = 1;
  5. $pi_4 = 0;
  6.  
  7. $i = 1000;  // 1000000000 to było za dużo, przynajmniej mój interpreter nie wyrobił w 30 sekund  ;]
  8.  
  9. for($i; $i > 0 ; $i--)
  10. {
  11.   $pi_4 += ($znak * 1.0) / $mianownik;
  12.   $mianownik += 2;
  13.   $znak = -$znak;
  14. }
  15.  
  16. $pi = 4.0 * $pi_4;
  17.  
  18. echo round($pi, 10), '<br />'; // zamiast html'owego <br />  może być php'owe "\n" ;)
  19. ?>
wert1
Dziala ale oblicza PI nie dokladnie zreszta sam zobacz : http://wert.bee.pl/1.php
wookieb
Bo zaokragla... Poza skopiowaniem mogles sobie zobaczyc co robia poszczegolne funkcje.
ziqzaq
Witam.
Takie pytanie z ciekawości. Musisz _obliczać_ pi?
Może wystarczy:
  1. <?php
  2. echo pi();
  3. // lub
  4. echo M_PI;
  5. ?>

Manual: http://pl2.php.net/pi
michalg
Nie sprawdzałem tego, ale czy zamiast:

$pi_4 += ($znak * 1.0) / $mianownik;

Nie powinno być? :
$pi_4 += $znak * 1.0 / $mianownik;

Swoją drogą zastanawiam się, na ile taki algorytm może być dokładny, jeżeli opiera się na arytmetyce zmiennoprzecinkowej, która do zbyt dokładnych nie należy.
wert1
bo zwykłe PI ma ograniczenia :/

to jak to zrobić bez zaokrąglania ?
michalg
Cytat(michalg @ 8.12.2008, 21:03:58 ) *
Nie sprawdzałem tego, ale czy zamiast:

$pi_4 += ($znak * 1.0) / $mianownik;

Nie powinno być? :
$pi_4 += $znak * 1.0 / $mianownik;


Dobra, nieważne. Chyba już za późno na myślenie winksmiley.jpg

A u mnie na komputerze wynik jest całkiem inny:
3.1405926538

Edit:
I było zbyt małe.

@wert1
A o jakie ograniczenia Ci chodzi? Zbyt mała dokładność? Do ilu potrzebujesz?
Darti
bo zwykły phpowy math ma ograniczoną dokładność, użyj BC Math jak chcesz dokładniej
ziqzaq
Ok. Rozumiem.
Więc może takie rozwiązania.
Potrzebujesz włączonego bcmath w php (phpinfo() i "--enable-bcmath") i funkcje:
- bcpi(),
- szybsze bcpi() smile.gif,
- jeszcze szybsze bcpi() winksmiley.jpg,
- i na koniec dopi()

Przetestowałem na szybko pierwszą z góry i wydaje się być ok, więc daj znać czy trafiłem w to co chciałeś.

Acha i w co najmniej jednej z tych funkcji jest niezdefiniowana zmienna "$n", więc po linii "$p = 1;" dodaj "$n = 0;" (to tak na wypadek gdybyś miał error_reporting = E_ALL w php.ini)
wert1
http://wert.bee.pl/1.php zobacz teraz sa 3 rozne wyniki :/

moj kod
  1. <br>A to zwykłe pi(); <br>
  2. <?
  3. echo substr(pi(), 0, 1000);
  4. ?>
  5. <Br>////////////////////////////////////////////////////////////////////<br>
  6. To jest ten skrypt :
  7. <br><br><br>
  8. <?php
  9.  
  10. $mianownik = 1;
  11. $znak = 1;
  12. $pi_4 = 0;
  13.  
  14. $i = 20;  // 1000000000 to było za dużo, przynajmniej mój interpreter nie wyrobił w 30 sekund  ;]
  15.  
  16. for($i; $i > 0 ; $i--)
  17. {
  18.  $pi_4 += ($znak * 1.0) / $mianownik;
  19.  $mianownik += 2;
  20.  $znak = -$znak;
  21. }
  22.  
  23. $pi = 4.0 * $pi_4;
  24.  
  25. echo round($pi, 10), '<br />'; // zamiast html'owego <br />  może być php'owe "\n" ;)
  26. ?>
  27. <?
  28.  
  29. function dopi($pidigits)
  30.    {
  31.        $pidigits += 10; //add 10 digits that will be removed later (last few digits tend to be inprecise)
  32.        bcscale($pidigits);
  33.        $origr = log($pidigits, 10);
  34.        $r= $origr;
  35.        $i=0;
  36.        $or=0;
  37.        $ffact = 1;
  38.        $sfact = 1;
  39.        while(bccomp($or,$r))
  40.        {
  41.            $i++;
  42.            $ffact = bcmul($i, $ffact);
  43.            $or=$r;
  44.            $b = $ffact;
  45.            $b = bcpow($b, 2);
  46.            $z = bcpow(2, $i+1);
  47.            $b = bcmul($b, $z);
  48.            $sfact = bcmul($sfact, bcmul(2*$i-1, 2*$i));
  49.            $z = $sfact;
  50.            $b = bcdiv($b,$z);
  51.            $r = bcadd($r, $b);
  52.        }
  53.        return substr(bcsub($r, 2 + $origr), 0, strlen($r) - 10);
  54.    }
  55.  
  56. echo dopi(20);
  57. echo "<BR>";
  58.  
  59. function bcpi($precision){
  60.    $limit = ceil(log($precision)/log(2))-1;
  61.    bcscale($precision+6);
  62.    $a = 1;
  63.    $b = bcdiv(1,bcsqrt(2));
  64.    $t = 1/4;
  65.    $p = 1;
  66.    while($n < $limit){
  67.        $x = bcdiv(bcadd($a,$b),2);
  68.        $y = bcsqrt(bcmul($a, $b));
  69.        $t = bcsub($t, bcmul($p,bcpow(bcsub($a,$x),2)));
  70.        $a = $x;
  71.        $b = $y;
  72.        $p = bcmul(2,$p);
  73.        ++$n;
  74.    }
  75.    return bcdiv(bcpow(bcadd($a, $b),2),bcmul(4,$t),$precision);
  76. }
  77. echo bcpi(20);
  78. ?>


ziqzaq Jak rozwiaze temat to dostaniesz +
michalg
Nie do końca wiem, do czego Ci jest to wszystko potrzebne, ale może być też inne rozwiązanie.

W internecie znajdziesz rozwinięcia PI nawet do kilku milionów miejsc po przecinku. Można by to było zapisać do jakiegoś pliku i potem odczytywać fragment tego pliku - zależy z jaką dokładnością będziesz potrzebował liczbę PI.
wert1
to musi byc obliczane !

EDIT:
Juz rozwiazalem
ziqzaq
Witam, super.
Podziel się z nami gdzie był/zrobiłeś błąd bo aż sam z ciekawości teraz sprawdziłem i...
U siebie użyłem funkcji bcpi() ze strony http://mgccl.com/2007/01/23/even-more-pi/.
Zgarnąłem wartość pi ze strony http://www.dbooth.net/internerd/pifinders.cfm (nie wiem, może to zła wartość?)
Następnie wygenerowałem funkcją bcpi() wartość pi do 500 miejsca po przecinku i porównałem z gotowcem ze strony. Są identyczne.
wert1
ten kod z C++ ktory oblicza PI jest bledny natomiast pi(); zaokragla ostatnia liczbe
jeszcze raz dzieki za pomoc winksmiley.jpg
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.