computing_pi.pl 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #!/usr/bin/perl
  2. # Code from:
  3. # http://www.perlmonks.org/?node_id=992580
  4. use 5.010;
  5. use strict;
  6. use warnings;
  7. use lib qw(../lib);
  8. use Math::AnyNum;
  9. my $digits = int($ARGV[0] // 0) || 60;
  10. {
  11. say "Newton iteration, using Taylor series of sine and cosine.";
  12. local $Math::AnyNum::PREC = log(10)/log(2) * $digits;
  13. my $b = Math::AnyNum->new(0);
  14. my $x = $b + 0.5;
  15. my %x;
  16. while (!$x{$x}++) {
  17. my $m = 1;
  18. my $s = 0;
  19. my $c = 1;
  20. my $k = 0;
  21. while (0 != $m) {
  22. $s += $m = $m * $x / ++$k;
  23. $c += $m = -$m * $x / ++$k;
  24. $m = $m->round(-$digits);
  25. }
  26. $x += (0.5 - $s) / $c;
  27. $x = $x->round(-$digits);
  28. }
  29. say "pi = " . (6 * $x);
  30. }
  31. {
  32. say "Using Taylor series of arctangent.";
  33. local $Math::AnyNum::PREC = log(10)/log(2) * $digits;
  34. my $b = Math::AnyNum->new(0);
  35. my $x = 2 - sqrt($b + 3);
  36. my $f = -$x * $x;
  37. my $m = $x * ($b + 12);
  38. my $a = $m;
  39. my $k = 1;
  40. while (0 != $m) {
  41. $m *= $f;
  42. $k += 2;
  43. $a += $m / $k;
  44. $m = $m->round(-$digits);
  45. }
  46. $a = $a->round(-$digits);
  47. say "pi = $a";
  48. }