http://www.perlmonks.org?node_id=58619

   1: #!/usr/bin/perl
   2: # This is a quick program to calculate pi using the Monte Carlo method.
   3: # I recomend inputting  a value for $cycles greater that 1000. 
   4: # I am working on a detailed explanation of how and why this works. 
   5: # I will add it as soon as I'm done.
   6: use strict;
   7: my ($cycles, $i, $yespi, $pi) = 0;
   8: srand;
   9: #print "Please enter number of cycles\n";
  10: print "Please enter the amount of cycles:";
  11: chomp($cycles = <STDIN>);
  12: while ($i < $cycles) {
  13:     my ($x, $y, $cdnt) = 0;
  14:     $x = rand;
  15:     $y = rand;
  16:     $cdnt = $x**2 + $y**2;
  17:     if ($cdnt <= 1) {
  18: 	++$yespi;
  19: }    
  20: ++$i;
  21: }
  22: $pi = ($yespi / $cycles) * 4;
  23: print "Pi is $pi\n";

Replies are listed 'Best First'.
Re: Pi calculator
by thaigrrl (Monk) on Feb 15, 2001 at 23:19 UTC
    I found this to be very cool. I wrote a paper on AI and the Monte Carlo Method in college so I found it even more interesting. Not a very efficient method of calculating PI but really trivial because of the accuracy of PI as the cycles increase. Did you come up with this on your own? Is this based on the Buffon pin drop method, where he drops a pin of length X on a page of parallel lines? If so bravo I found it really entertaining :)
    Also the use of srand and rand (forcing the random number to be less than 1 but greater than zero) is pretty sweet. I wouldn't have thought of that.

    Buffon's Needle Experiment:
    If we have a uniform grid of parallel lines, unit distance apart and if we drop a needle of length k < 1 on the grid, the probability that the needle falls across a line is 2k/pi. Various people have tried to calculate by throwing needles. The most remarkable result was that of Lazzerini (1901), who made 34080 tosses and got

    PI = 355/113 = 3.1415929

    UPDATE

    New comment:
    on Thurs Feb 15 2001 at 16:40 (EST)
    I actually did some testing on this, and it is pretty random, I plugged in a bunch of numbers, and got 3.14... with the cycle 754854. I retested the numbers and I got some results:

    $yespi / cycle * 4 = PI 593360 / 754854 * 4 = is 3.14423716374292 593195 / 754854 * 4 = is 3.14336282247958 592995 / 754854 * 4 = is 3.14230301488765

    The problem here is not srand. Think of an x,y plane with a 1x1 square with its center located at (0,0). Inside this square is a circle with a radius of 1, also with its center at (0,0) what is happening in this algorithm is you are coming up with two random numbers but only couting your $yespi if (x^2 + y^2) <=1 . This could be any coordinate inside the square, therefore all of the points outside the circle but inside the square will not equal pi. But everything inside the circle will. You get a number close to PI more often than not because the area within the circle is greater than that outside of the circle but within the square. Does this make sense?
      Thank you. I did not come up with the method if that's what you are asking. Its based on a circle with a radius of 1 and a square dartboard with each sid being 2. The circle is oin the square. WHen you throw the dart, there is a propability of pi/4 that it will land.... Can you please help me with something? I modified the code to repeat the calculations a certain number of times adding 10 cycles each time. As it got farther than 50,000 it started going into 3.16... while it wa at 3.14 in the 50,000 area. Is this a nuence of the method, or is this have to do with srand not being completly random? Also after 50,000 or so, not once did it generate pi starting with 3.14 ?!?
        Running for 10,000,000 twice I got 3.1405 the first run, and 3.1424 the second. (for an average of 3.1415) It's quite likely your rand() isn't perfect. (neither is mine 10,000,000 runs should give me a digit or two more accuracy).

        Anyway, here is my favorite approximation for pi, mainly because it only uses the number 2. Even though two is normally a computer friendly number, this algorithm isn't, because it also uses sqrt's. With my perl, 14 iterations is gives the maximum accuracy: 3.14159265480759

        #!/usr/bin/perl -w use strict; print "Enter how many iterations:\n"; chomp(my $i = <>); my $x = $i - 1; my $y = sqrt(2); do { $y = sqrt(2 + $y) while (--$x); $y = sqrt(2 - $y); } if $x; my $z = $y * (2 ** $i); print "Pi is close to: $z\n";

        So, while not the best, but I have some strange affinity to it. :)

        Ciao,
        Gryn

        p.s. Sorry for the cryptic code for a quick decrypt its: (2**n)*sqrt(2-sqrt(2+sqrt(2+sqrt(2+sqrt(2))))) with the number of 2's inside the sqrt equaling n.

      Thaigrrrr Maybe I did not quite understand you. Thats exactly how the algorithm is supposed to work. The circle has a radius of 1, so it's area is pi (A=pi*r**2) and the square has an area of 4 since each side is 2. So the propability of any coordinate landing in the circle becomes area of circle/area of square or pi/4 so we divide the number that landed in the circle by the number overal and multiply the result by 4. Is this what you meant?
        Oops forgot to log in, above post was mine
      Could you provide a link? I'm too lazy to search, but I would still like to read more about this particular approach.

      Supposedly there is a modern pi generating algorithm which takes constant time to generate any given digit of pi requested.

      Ciao,
      Gryn

        The former is available from Google, laziness is no excuse. The latter only works for base 16.
Obfuscated Pi calculator
by grinder (Bishop) on Feb 20, 2001 at 21:24 UTC

    That's very nice. I might squirrel that way for an OPC contest entry. I once played around with a polynomial expansion, but after many hours CPU time the code got as far as 3.14159264

    0: #! /usr/bin/perl -lw 1: 2: use strict; 3: 4: my $pi = do{ 5: my $w = 6*do { my $y=0; $y+=((sub { eval join(' 6: +', map{ eval eval join('/',$_[0], do{local $"= 7: "+";eval "@{[($_)x$_]}"}) } $_[0]+$_[1]*$_[2].. 8: $_[2]*($_[1]+$_[0]))}, sub { eval join('+', map 9: {eval eval join('/',$_[0], do{local $"="*";eval 10: "@{[$_,$_]}"}) } $_[0]+$_[1]*$_[2] ..$_[2]*($_[ 11: 1]+ $_[0]) ) })[$_>10])->(1,$_,100) foreach(0.. 12: 1000000); $y}; my $y=(1+$w/1)/2; $y=($y+$w/$y)/ 13: 2 foreach(0..100);$y}; 14: 15: print $pi;

    Plus it chewed up core like crazy....

Re: Pi calculator
by Beatnik (Parson) on Aug 23, 2001 at 18:26 UTC
Re: Pi calculator
by John M. Dlugosz (Monsignor) on Aug 24, 2001 at 02:56 UTC
    This is one method for testing your random number generator, too. I've seen checking code that along with distributions, chi-square, etc. also does this and sees if the value converges on the correct value. It's a very sensitive way of detecting biases.
Re: Pi calculator
by mjcrawford2 (Initiate) on Apr 11, 2013 at 17:02 UTC
    More accuately: $PI = 4.0 * atan2(1.0,1.0);