Home  >  Article  >  Backend Development  >  Code to calculate Pi using the BBP formula

Code to calculate Pi using the BBP formula

WBOY
WBOYOriginal
2016-07-25 09:01:232681browse
The BBP formula claims to be able to directly obtain the Nth result of Pi. Originally, I thought that the acquisition speed would be the same at any position, but download one from bellard's homepage (http://bellard.org/pi/) After testing the improved C program, I found that the larger N, the longer the calculation time. After I converted it to PHP code, it would take more than 1 minute to calculate the 1Kth digit. The calculation of the original C program was also very slow.

This program will only output 9 numbers at a time (囧rz, I don’t know how to change it to output more numbers)
  1. /**
  2. * Pi calculation (BBP)
  3. * @author Moyo
  4. * @url http://moyo.uuland.org/code/php-pi-calc/
  5. * @version 1.0
  6. * @ date 2013.01.12
  7. */
  8. class pi
  9. {
  10. public static function calc($__N__)
  11. {
  12. $n = (int)$__N__;
  13. $av = $ a = $vmax = $N = $num = $den = $k = $kq = $kq2 = $t = $v = $s = $i = 0;
  14. $sum = 0.0;
  15. $N = (int) (($n + 20) * log(10) / log(2));
  16. $sum = 0;
  17. for ($a = 3; $a <= (2 * $N); $a = self: :next_prime($a))
  18. {
  19. $vmax = (int)(log(2 * $N) / log($a));
  20. $av = 1;
  21. for ($i = 0; $i < $vmax; $i ++)
  22. {
  23. $av = ($av * $a);
  24. }
  25. $s = 0;
  26. $num = 1;
  27. $den = 1;
  28. $v = 0;
  29. $ kq = 1;
  30. $kq2 = 1;
  31. for ($k = 1; $k <= $N; $k ++)
  32. {
  33. $t = $k;
  34. if ($kq >= $a )
  35. {
  36. do
  37. {
  38. $t = (int)($t / $a);
  39. $v --;
  40. }
  41. while (($t % $a) == 0);
  42. $kq = 0 ;
  43. }
  44. $kq ++;
  45. $num = self::mul_mod($num, $t, $av);
  46. $t = (2 * $k -1);
  47. if ($kq2 >= $ a)
  48. {
  49. if ($kq2 == $a)
  50. {
  51. do
  52. {
  53. $t = (int)($t / $a);
  54. $v ++;
  55. }
  56. while (($t % $a) == 0);
  57. }
  58. $kq2 -= $a;
  59. }
  60. $den = self::mul_mod($den, $t, $av);
  61. $kq2 += 2;
  62. if ($ v > 0)
  63. {
  64. $t = self::inv_mod($den, $av);
  65. $t = self::mul_mod($t, $num, $av);
  66. $t = self::mul_mod ($t, $k, $av);
  67. for ($i = $v; $i < $vmax; $i ++)
  68. {
  69. $t = self::mul_mod($t, $a, $ av);
  70. }
  71. $s += $t;
  72. if ($s >= $av)
  73. {
  74. $s -= $av;
  75. }
  76. }
  77. }
  78. $t = self::pow_mod(10 , ($n - 1), $av);
  79. $s = self::mul_mod($s, $t, $av);
  80. $sum = (double)fmod((double)$sum + (double)$ s / (double)$av, 1.0);
  81. }
  82. return array(
  83. 'n' => $n,
  84. 'v' => sprintf('%09d', (int)($sum * 1e9) )
  85. );
  86. }
  87. private static function next_prime($n)
  88. {
  89. do
  90. {
  91. $n ++;
  92. }
  93. while (!self::is_prime($n));
  94. return $n;
  95. }
  96. private static function is_prime($n)
  97. {
  98. $r = $i = 0;
  99. if (($n % 2) == 0)
  100. {
  101. return 0;
  102. }
  103. $r = (int)(sqrt ($n));
  104. for ($i = 3; $i <= $r; $i += 2)
  105. {
  106. if (($n % $i) == 0)
  107. {
  108. return 0;
  109. }
  110. }
  111. return 1;
  112. }
  113. private static function mul_mod($a, $b, $m)
  114. {
  115. return fmod((double)$a * (double)$b, $m);
  116. }
  117. private static function inv_mod($x, $y)
  118. {
  119. $q = $u = $v = $a = $c = $t = 0;
  120. $u = $x;
  121. $v = $y;
  122. $ c = 1;
  123. $a = 0;
  124. do
  125. {
  126. $q = (int)($v / $u);
  127. $t = $c;
  128. $c = $a - $q * $c;
  129. $a = $t;
  130. $t = $u;
  131. $u = $v - $q * $u;
  132. $v = $t;
  133. }
  134. while ($u != 0);
  135. $a = $ a % $y;
  136. if ($a < 0)
  137. {
  138. $a = $y + $a;
  139. }
  140. return $a;
  141. }
  142. private static function pow_mod($a, $b, $m)
  143. {
  144. $r = $aa = 0;
  145. $r = 1;
  146. $aa = $a;
  147. while (1)
  148. {
  149. if ($b & 1)
  150. {
  151. $r = self::mul_mod( $r, $aa, $m);
  152. }
  153. $b = $b >> 1;
  154. if ($b == 0)
  155. {
  156. break;
  157. }
  158. $aa = self::mul_mod($ aa, $aa, $m);
  159. }
  160. return $r;
  161. }
  162. }
  163. ?>
Copy code


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn