File Coverage

blib/lib/ConstantCalculus/CircleConstant.pm
Criterion Covered Total %
statement 22 127 17.3
branch 0 38 0.0
condition n/a
subroutine 8 17 47.0
pod 0 9 0.0
total 30 191 15.7


line stmt bran cond sub pod time code
1             package ConstantCalculus::CircleConstant;
2              
3             # Set the VERSION.
4             our $VERSION = "0.01";
5              
6             # Load the Perl pragmas.
7 1     1   58090 use 5.008009;
  1         4  
8 1     1   5 use strict;
  1         2  
  1         17  
9 1     1   4 use warnings;
  1         2  
  1         36  
10              
11             # Load the Perl pragma Exporter.
12 1     1   6 use vars qw(@ISA @EXPORT @EXPORT_OK);
  1         8  
  1         56  
13 1     1   6 use Exporter 'import';
  1         2  
  1         92  
14              
15             # Base class of this (tron_addr) module.
16             our @ISA = qw(Exporter);
17              
18             # Exporting the implemented subroutine.
19             our @EXPORT = qw(
20             pi_chudnovsky
21             pi_chudnovsky_algorithm
22             tau_chudnovsky
23             tau_chudnovsky_algorithm
24             $CONTROL_OUTPUT
25             );
26              
27             # Exporting the multiply and divide routine on demand basis.
28             @EXPORT_OK = qw(
29             truncate_places
30             chudnovsky_terms
31             factorial
32             pi
33             tau
34             );
35              
36             # Define the Perl BEGIN block.
37             BEGIN {
38             # Set the subroutine aliases.
39 1     1   5 *pi = \&pi_chudnovsky;
40 1         26 *tau = \&tau_chudnovsky;
41             };
42              
43             # Disable a warning.
44 1     1   5 no warnings 'recursion';
  1         2  
  1         35  
45              
46             # Load the Perl module.
47 1     1   449 use bignum;;
  1         4322  
  1         6  
48              
49             # Set the precision for bignum.
50             bignum -> precision(-14);
51              
52             # Set the zeros.
53             my $NEXT_DIGIT = int((log(151931373056000)/log(10))+1);
54              
55             # Set verbose flag.
56             our $CONTROL_OUTPUT = 0;
57              
58             # Flush output immediately to the terminal window.
59             local $| = 1;
60              
61             #------------------------------------------------------------------------------#
62             # Subroutine is_unsigned_int() #
63             #------------------------------------------------------------------------------#
64             sub is_unsigned_int {
65             # Assign the subroutine argument to the local variable.
66 0 0   0 0   my $arg = (defined $_[0] ? $_[0] : '');
67             # Set the Perl conform regex pattern.
68 0           my $re = qr/^(([1-9][0-9]*)|0)$/;
69             # Check the argument with the regex pattern.
70 0 0         my $is_unsigned_int = (($arg =~ $re) ? 1 : 0);
71             # Return 0 (false) or 1 (true).
72 0           return $is_unsigned_int;
73             };
74              
75             # ---------------------------------------------------------------------------- #
76             # Subroutine factorial() #
77             # ---------------------------------------------------------------------------- #
78             sub factorial {
79 0     0 0   my $n = $_[0];
80 0 0         my $fac = ($n == 0 ? 1 : factorial($n-1)*$n);
81 0           return $fac;
82             };
83              
84             # ---------------------------------------------------------------------------- #
85             # Subroutine chudnovsky_terms() #
86             # ---------------------------------------------------------------------------- #
87             sub chudnovsky_terms {
88             # Assign the subroutine argument to the local variable.
89 0 0   0 0   my $places = (defined $_[0] ? $_[0] : 0);
90             # Determine the estimated number of terms.
91 0           my $number_terms = undef;
92 0 0         if ($places <= 1) {
    0          
93 0           $number_terms = $places;
94             } elsif ($places <= 14) {
95 0           $number_terms = 1;
96             } else {
97 0           $number_terms = int($places / $NEXT_DIGIT) + 2;
98 0 0         $number_terms += ($number_terms % 2 == 0 ? 1 : 0);
99             };
100             # Return the estimated number of terms.
101 0           return $number_terms;
102             };
103              
104             # ---------------------------------------------------------------------------- #
105             # Subroutine truncate_places() #
106             # ---------------------------------------------------------------------------- #
107             sub truncate_places {
108 0     0 0   my $decimal = $_[0];
109 0           my $places = $_[1];
110 0           my $factor = 10**$places;
111 0           $decimal = int($decimal*$factor) / ($factor);
112 0           $decimal = substr($decimal, 0, $places+2);
113 0           return $decimal;
114             };
115              
116             # ---------------------------------------------------------------------------- #
117             # Subroutine control_output() #
118             # ---------------------------------------------------------------------------- #
119             sub control_output {
120 0     0 0   my $places = $_[0];
121 0           my $terms = $_[1];
122 0           my $precision = $_[2];
123 0           my $type = $_[3];
124 0           my $formula = $_[4];
125 0           printf("%s\n", "Calculation Data");
126 0           printf("%s\n", "================");
127 0           printf("%-10s %s\n", "Formula:", $formula);
128 0           printf("%-10s %s\n", "Type:", $type);
129 0           printf("%-10s %s\n", "Precision:", $precision);
130 0           printf("%-10s %s\n", "Places:", $places);
131 0           printf("%-10s %s\n", "Terms:", $terms);
132             };
133              
134             # ---------------------------------------------------------------------------- #
135             # Subroutine pi_chudnovsky_algorithm() #
136             # ---------------------------------------------------------------------------- #
137             sub pi_chudnovsky_algorithm {
138             # Assign the subroutine arguments to the local variables.
139 0 0   0 0   my $places = (defined $_[0] ? $_[0] : 0);
140 0 0         my $n = (defined $_[1] ? $_[1] : 0);
141 0 0         my $p = (defined $_[2] ? $_[2] : 0);
142             # Set the precision.
143 0           bignum -> precision(-$p);
144             # Initialise the return variable.
145 0           my $pi = 0;
146             # Set the local integer constants.
147 0           my $c0 = 545140134;
148 0           my $c1 = 13591409;
149 0           my $c2 = 640320;
150 0           my $c3 = 4270934400;
151 0           my $c4 = 10005;
152             # Set the initial values.
153 0           my $a_k = 0;
154 0           my $a_sum = 0;
155 0           my $numerator = 0;
156 0           my $denominator = 0;
157             # Set the sign to 1.
158 0           my $sign = 1;
159             # Run index is of type int.
160 0           for (my $k = 0; $k <= $n; $k++) {
161             # Calculate numerator and denominator.
162 0           $numerator = factorial(6*$k)*($c0*$k+$c1);
163 0           $denominator = factorial(3*$k)*(factorial($k)**3)*($c2**(3*$k));
164             # Calculate the quotient.
165 0           $a_k = $sign*($numerator/$denominator);
166             # Add quotient to total sum.
167 0           $a_sum += $a_k;
168             # Change the sign.
169 0           $sign *= -1;
170             };
171             # Calculate the value of Pi.
172 0           $pi = $c3 / (sqrt($c4)*$a_sum);
173             # Return the value of Pi.
174 0           return "$pi";
175             };
176              
177             # ---------------------------------------------------------------------------- #
178             # Subroutine pi_chudnovsky() #
179             # ---------------------------------------------------------------------------- #
180             sub pi_chudnovsky {
181             # Assign the subroutine arguments to the local variables.
182 0 0   0 0   my $places = (defined $_[0] ? $_[0] : 0);
183             # Check if places are valid numbers.
184 0 0         if (is_unsigned_int($places) != 1) {
185 0           print "The given number of places is not valid. Terminating processing. Bye!\n";
186 0           exit;
187             };
188             # Calculate the number of needed terms.
189 0           my $terms = chudnovsky_terms($places);
190             # Set the precision for the calculation.
191 0           my $precision = $places + $NEXT_DIGIT;
192             # Print control output to the terminal window.
193 0 0         if ($CONTROL_OUTPUT == 1) {
194 0           my $formula = "Chudnovsky (Pi)";
195 0           my $type = "decimal";
196 0           control_output($places, $terms, $precision, $type, $formula);
197             };
198             # Get value of Pi from calculation.
199 0           my $pi = pi_chudnovsky_algorithm($places, $terms, $precision);
200             # Cut the decimal number to the needed places.
201 0           $pi = truncate_places($pi, $places);
202             # Return the value of pi.
203 0           return "$pi";
204             };
205              
206             # ---------------------------------------------------------------------------- #
207             # Subroutine tau_chudnovsky_algorithm() #
208             # ---------------------------------------------------------------------------- #
209             sub tau_chudnovsky_algorithm {
210             # Assign the subroutine arguments to the local variables.
211 0 0   0 0   my $places = (defined $_[0] ? $_[0] : 0);
212 0 0         my $n = (defined $_[1] ? $_[1] : 0);
213 0 0         my $p = (defined $_[2] ? $_[2] : 0);
214             # Set the precision.
215 0           bignum -> precision(-$p);
216             # Initialise the return variable.
217 0           my $tau = 0;
218             # Set the local integer constants.
219 0           my $c0 = 545140134;
220 0           my $c1 = 13591409;
221 0           my $c2 = 640320;
222 0           my $c3 = 4270934400;
223 0           my $c4 = 10005;
224             # Set the initial values.
225 0           my $a_k = 0;
226 0           my $a_sum = 0;
227 0           my $numerator = 0;
228 0           my $denominator = 0;
229             # Set the sign to 1.
230 0           my $sign = 1;
231             # Run index is of type int.
232 0           for (my $k = 0; $k <= $n; $k++) {
233             # Calculate numerator and denominator.
234 0           $numerator = factorial(6*$k)*($c0*$k+$c1);
235 0           $denominator = factorial(3*$k)*(factorial($k)**3)*($c2**(3*$k));
236             # Calculate the quotient.
237 0           $a_k = $sign*($numerator/$denominator);
238             # Add quotient to total sum.
239 0           $a_sum += $a_k;
240             # Change the sign.
241 0           $sign *= -1;
242             };
243             # Calculate the value of Tau.
244 0           $tau = (2*$c3) / (sqrt($c4)*$a_sum);
245             # Return the value of Tau.
246 0           return "$tau";
247             };
248              
249             # ---------------------------------------------------------------------------- #
250             # Subroutine tau_chudnovsky() #
251             # ---------------------------------------------------------------------------- #
252             sub tau_chudnovsky {
253             # Assign the subroutine arguments to the local variables.
254 0 0   0 0   my $places = (defined $_[0] ? $_[0] : 0);
255             # Check if places are valid numbers.
256 0 0         if (is_unsigned_int($places) != 1) {
257 0           print "The given number of places is not valid. Terminating processing. Bye!\n";
258 0           exit;
259             };
260             # Calculate the number of needed terms.
261 0           my $terms = chudnovsky_terms($places);
262             # Set the precision for the calculation.
263 0           my $precision = $places + $NEXT_DIGIT;
264             # Print control output to the terminal window.
265 0 0         if ($CONTROL_OUTPUT == 1) {
266 0           my $formula = "Chudnovsky (Tau)";
267 0           my $type = "decimal";
268 0           control_output($places, $terms, $precision, $type, $formula);
269             };
270             # Get value of Pi from calculation.
271 0           my $tau = tau_chudnovsky_algorithm($places, $terms, $precision);
272             # Cut the decimal number to the needed places.
273 0           $tau = truncate_places($tau, $places);
274             # Return the value of pi.
275 0           return "$tau";
276             };
277              
278             1;
279             __END__