More fun with Perl and Pi

n1vux on 2007-02-01T04:24:33

A year ago #28505, I answered a question on Perl Monks about calculating Pi with Math::BigFloat. Today the always funny XKCD made me go back and look at that program, as I had two rather less useful approximations of Pi to calculate now.

I'm somewhat surprised that Math::BigFloat doesn't have an AntiLog function for Euler's base 'e' (natural exponent). Hard coding it as a constant isn't terrible, but not nice either. I suppose I could compute it too ...

#!/usr/local/bin/perl

### # Adaptation of my prior program to test XKCD's formulas 2007-01-31 # (9^2 + 19^2/22)^(1/4) = PI # (e^pi - pi) = 20 - delta # http://xkcd.com/c217.html ####

use strict; use warnings; use Math::BigFloat;

my $DIGS= ($ARGV[0]||10); Math::BigFloat->div_scale($DIGS+5);

# (9^2 + 19^2/22) = PI print "(9^2 + 19^2/22) = PI ? \n"; my $pi = new Math::BigFloat '9'; $pi->bpow(2); $pi->bpow(2);

my $term= new Math::BigFloat'19'; $pi->badd($term->bpow(2)->bdiv(22));

# $pi->bsqrt()->bsqrt(); $pi->broot(4);

# compare to known-good from bottom of file my $PI=(new Math::BigFloat ); my $good=$PI->copy()->round($DIGS+2); print $good, "\n"; print $pi->round($DIGS+1), "\n"; print ( ($good - $pi), "\n");

##################### # part 2 # (e^pi - pi) = 20 - delta print " (e^pi - pi) = 20 ?\n"; $pi=$PI->copy(); # my $e = (new Math::BigFloat '10')->bpow((new Math::BigFloat 1)/(new Math::BigFloat $LOG_10)); my $E = new Math::BigFloat '2.71828_18284_59045_23536'; my $VENTE=new Math::BigFloat '20.0'; print "$VENTE \n"; my $diff = $E->copy()->bpow($PI)->bsub($PI); print $diff->round($DIGS)," \n"; print " ",(($VENTE - $diff)->round(3)), "\n";



# some accurate pi to compare output to: __DATA__ 3.14159265358979323846264338327950288419716939937510582097494459230781640628621


Dup!

Mr. Muskrat on 2007-02-01T15:18:55

$pi->bpow(2); is duplicated.

Calculating digits of pi-Gaussian method

scot on 2007-02-01T19:54:22

I came up with the following code recently as an experiment:


use strict;
use Math::BigFloat;
use Time::HiRes;

my $x = Math::BigFloat->new(my $str);
$x->accuracy(100);
my $start = (times)[0];
$x=48*atan2(1,18)+32*atan2(1,57)-20*atan2(1,239);
my $end = (times)[0];
my $elapsed = $end-$start;
printf "%.100f".$x."\n";
printf "that took %.100f CPU seconds.\n",$elapsed;

My source for the calculation of pi is a formula attributed to Gauss in the 1977 Van Nostrand Reinhold "Encyclopedia of Mathematics." I was interested in seeing how fast this would run on different machines that I have.