I am trying to make a C program that calculates the value of Pi
from the infinite series, aka Leibniz series, and display it to the user. My problem is that I need to display a special message that appears when the program hits the first 3.14
, and the first 3.141
. That special message should include in which iteration of the loop did the the number become 3.14
and 3.141
. I am not lazy so a found a way to make the infinite series but the second part I couldn't figure out, so what should I add to my code to make it display the special message?
#include <stdio.h>
int main(void) {
int i, den; // denominator and counter
double pi = 4;
for (i = 0; i < 10000; i ) {
den = i * 2 3;
// (4 - 4/3 4/5 -4/7 4/9 -......)
if (i % 2 == 0) {
pi = pi - (4.0 / den);
}
else {
pi = pi (4.0 / den);
}
printf("pi = %lf\n", pi);
}
}
CodePudding user response:
Here's a possible solution:
#include<stdio.h>
#include <math.h>
int
main (void)
{
int i, den; //denominator and counter
int reached_314, reached_3141;
double pi = 4;
reached_314 = reached_3141 = 0;
for (i = 0; i < 10000; i )
{
den = i * 2 3;
//(4 - 4/3 4/5 -4/7 4/9 -......)
if (i % 2 == 0)
pi -= 4.0 / den;
else
pi = 4.0 / den;
printf ("pi = %lf\n", pi);
if (!reached_314 && trunc (100 * pi) == 314)
{
printf ("Found 3.14 at iteration %d\n", i);
reached_314 = 1;
}
if (!reached_3141 && trunc (1000 * pi) == 3141)
{
printf ("Found 3.141 at iteration %d\n", i);
reached_3141 = 1;
}
}
}
The output is:
pi = 2.666667
pi = 3.466667
pi = 2.895238
...
pi = 3.150140
pi = 3.133118
pi = 3.149996
Found 3.14 at iteration 117
...
pi = 3.141000
pi = 3.142185
pi = 3.141000
Found 3.141 at iteration 1686
...
CodePudding user response:
Here is a version that compares the first n digits of a double cmp_n()
. Variables use minimal scope. The variable oracle
holds the truncated pi
to n
decimals. The values of oracle
must be stored in ascending order. I tweaked the pi formula to be a bit more compact format.
#include <math.h>
#include <stdio.h>
int cmp_n(double d1, double d2, size_t n) {
return fabs(trunc(pow(10, n) * d1) - trunc(pow(10, n) * d2)) < 1.0;
}
int main() {
double pi = 4;
size_t o = 0;
struct {
double pi[;
size_t n;
} oracle[] = {
{ 3.14, 2 },
{ 3.141, 3 }
};
for (int i = 0; i < 10000; i ) {
int den = i * 2 3;
//(4 - 4/3 4/5 -4/7 4/9 -......)
pi = ((i % 2) ? 4.0 : -4.0) / den;
int special = 0;
if(
o < sizeof(oracle) / sizeof(*oracle) &&
cmp_n(pi, oracle[o].pi, oracle[o].n)
) {
special = 1;
o ;
}
printf("pi = %.15f%2s\n", pi, special ? "*" : "");
}
}
and the relevant data (with line numbers);
$ ./a.out | nl -v0 | grep '*'
117 pi = 3.149995866593470 *
1686 pi = 3.141000236580159 *
Note: you need to add the "%.15lf" format string other the pi output is rounded. double
only gives you about 15 digits, and the cmp_n()
scales the number and this may not work as expected as you get close to the precision supported by double
.