// IMPORTANT: This project uses an extra compilation flag: -lquadmath
// Add this via Settings (gear icon in top right corner) -> Extra Compiler Flags
#include <quadmath.h>
#include <stdlib.h>
#include <stdio.h>
// PI_ACTUAL comes from https://www.piday.org/million/
#define PI_ACTUAL "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534"
const char * CalculateNilakanthaPi(int numElements)
{
__float128 pi = 3.0Q;
for (int i = 1; i <= numElements; i++)
{
__float128 term = 4.0Q / (2.0Q * i * (2.0Q * i + 1) * (2.0Q * i + 2));
if (i % 2)
pi += term;
else
pi -= term;
}
static char buffer[128];
const int precision = 35;
quadmath_snprintf(buffer, sizeof(buffer), "%.36Qg", precision, pi);
return buffer;
}
int FindFirstDifference(const char * seq1, const char * seq2)
{
int offset = 0;
for (const char * ch1 = seq1, * ch2 = seq2; *ch1 && *ch2 && *ch1 == *ch2; ch1++, ch2++)
offset++;
return offset;
}
void Approximate(int numElements)
{
const char * buffer = CalculateNilakanthaPi(numElements);
printf("Pi %8d: %s\n", numElements, buffer);
int difAt = FindFirstDifference(PI_ACTUAL, buffer);
printf("Accuracy: %-3d", difAt - 1);
for (int i = 0; i < difAt; i++)
putc(' ', stdout);
printf("^\n");
}
int main()
{
printf("Pi \"actual\": %s\n", PI_ACTUAL);
Approximate(10000000);
Approximate(1000000);
Approximate(100000);
Approximate(10000);
Approximate(1000);
Approximate(100);
Approximate(10);
return 0;
}