in reply to Re^2: porting C code to Perl -- solved
in thread porting C code to Perl
Update: Implemented the divisor suggestion by soonix.
Hi Discipulus,
To have Perl match the C output (regarding the number of characters), a missing append is needed at the end of the Perl script. The C code is found here and at stackoverflow. Regarding C, a fix is necessary described here (under Update 2) and here.
$pi .= $predigit; # <-- missing line print $pi =~ s/^03/3./r;
I validated using the following code, based on yours and replies by fellow monks. Notice the Perlish for my $k (0..$nines - 1) { ... } near the end of the script. In your demonstration, calling int on $predigit isn't necessary because $q contains an integer value; e.g. $q = int( ... ).
# The spigot algorithm for calculating the digits of Pi. # http://www.cut-the-knot.org/Curriculum/Algorithms/SpigotForPi.shtml use strict; use warnings; my $n = 100; my $len = int(10 * $n / 3) + 1; my $pi; my @a = (2) x $len; my $nines = 0; my $predigit = 0; for my $j (1..$n) { my $q = 0; for my $i (reverse 0..$len - 1) { my $x = 10 * $a[$i] + $q * ($i + 1); my $divisor = 2 * $i + 1; $a[$i] = $x % $divisor; $q = int($x / $divisor); } $a[0] = $q % 10; $q = int($q / 10); if (9 == $q) { ++$nines; } elsif (10 == $q) { $pi .= $predigit + 1; for my $k (0..$nines - 1) { $pi .= 0; } $predigit = $nines = 0; } else { $pi .= $predigit; $predigit = $q; if (0 != $nines) { for my $k (0..$nines - 1) { $pi .= 9; } $nines = 0; } } } $pi .= $predigit; print $pi, "\n";
Pi computed to 10,000 digits is found here.
Update: The above runs 1.4 times faster with small changes. Basically, use integer. Thanks, haukex.
2a3 > use integer; 5c6 < my $len = int(10 * $n / 3) + 1; --- > my $len = 10 * $n / 3 + 1; 20c21 < $q = int($x / $divisor); --- > $q = $x / $divisor; 24c25 < $q = int($q / 10); --- > $q = $q / 10;
Regards, Mario
|
---|