I wrote a program that approximates Pi by using polygons. I used the formulars in the picture beyond.
In my code they are called innerPoly
(\$c_{2n}\$) and outerPoly
(\$C_{2n}\$).
And since you can calculate the circumference of a 2n-polygon with knowing the circumference of a n-polygon you will get the circumferences \$C_8\,ドル \$C_{16}\,ドル \$C_{32}\$ etc., knowing \$C_4\$.
$$ \begin{array}{l} c_{2n} =& 2 \sqrt{2n^2-n\sqrt{(2n)^2-c_n^2}} \qquad&\textrm{for the inner polygon, with}\ c_4=4\sqrt{2} \\ C_{2n} =& \frac{4 n C_n}{2n + \sqrt{(2n)^2 + C_n^2}} &\textrm{for the outer polygon, with}\ C_4=8 \end{array} $$
My thoughts are:
Would it make it anyhow better when I have a function called
void PiApproximation()
that writes my values to stdout already? I mean technically you can always put your full code into themain()
-function, but when you have to use the same code-parts over and over again you should make a own function of it and call it, when u need it. So I guess in this case it will make no difference if I use an own function or calculate the circumferences and print it in the main-function.What else can I improve?
pi_approx.c
#include <stdio.h>
#include <math.h>
#define INNER_FOUR 4*sqrt(2); //circumference c_4 of the inner tetragon(square)
#define OUTER_FOUR 8 //circumference C_4 of the outer tetragon
int power(int n, int p);
int main(void)
{
int n = 4;
double innerPoly = INNER_FOUR;
double outerPoly = OUTER_FOUR;
printf("PI-APPROXIMATION USING POLYGONS\n");
printf("===============================\n\n");
printf(" n I c_n/2 I C_n/2 I\n");
printf("---------I-----------------I-----------------I\n");
for (int i=3; n<=8192; n=power(i,2), i++)
{
printf(" %4d I %1.8lf I %1.8lf I\n", n, innerPoly / 2, outerPoly / 2);
innerPoly = 2 * sqrt(2 * n*n - n*sqrt(4 * n*n - innerPoly*innerPoly)); //formular c_2n
outerPoly = (4 * n * outerPoly) / (2 * n + sqrt(4 * n*n + outerPoly*outerPoly)); //formular C_2n
}
return 0;
}
int power(int n, int p)
{
int pBuffer = 1;
for (int i=1; i <= n; i++)
{
pBuffer *= p;
}
return pBuffer;
}
1 Answer 1
You asked,
Would it make it better if I had a function called
PiApproximation
?The code in
main
does just one thing so it would not be an improvement to introduce a new function like this — the question would then be, what's the point ofmain
?There is a dependency between the initial value of
n
and the initial values ofinnerPoly
andouterPoly
. It would make sense to put all the initialization code together.Because
n
can never be negative it could be unsigned.The loop:
for (int i=3; n<=8192; n=power(i,2), i++)
is quite hard to follow because the loop variable is
i
but the termination condition is on a different variablen
. Because the loop variablei
is not used, it would be easier to follow the logic if you wrote:for (; n <= 8192; n *= 2)
(This also avoids the need for the
power
function.)The
l
modifier has no effect on theprintf
format specifier%f
, and so should be omitted.
-
\$\begingroup\$ I don't know the C preprocessor very well, but those
#define
scare me: iirc doing something likedouble sum = INNER_FOUR + OUTER_FOUR
or anything with code after the macro could break in interesting ways. What's the correct way to deal with that? \$\endgroup\$CAD97– CAD972017年04月15日 16:35:39 +00:00Commented Apr 15, 2017 at 16:35 -
1\$\begingroup\$ @CAD97: Parenthesize the macro expansion (see the comp.lang.c FAQ). \$\endgroup\$Gareth Rees– Gareth Rees2017年04月15日 16:42:59 +00:00Commented Apr 15, 2017 at 16:42
-
\$\begingroup\$ In my case I only use this constant circumferences of a 4-polygon as a start-value of my calculation, i.e. I do not really use them in a formular, where I can immediately see what this constant would mean in a determined context. \$\endgroup\$physics– physics2017年04月16日 20:30:43 +00:00Commented Apr 16, 2017 at 20:30
-
\$\begingroup\$ So in my case I could directly write on the variables
innerPoly
,outerPoly
my start-values at the begin of themain()
-program. What do you think about that? \$\endgroup\$physics– physics2017年04月16日 20:37:23 +00:00Commented Apr 16, 2017 at 20:37