For arbitrary precision in C, the shortest practical way is to use MPFR (with GMP under the hood).
This gives n digits after the decimal point, with precision limited only by memory/time (i.e., arbitrary precision).
Great constraint 👍 — readable, pure C, no external libs, arbitrary number of digits (limited by time/RAM).
This uses a classic spigot algorithm for π:
Compile/run:
If you want, I can also give an even shorter version (still readable) with fewer checks/comments.
Done — I wrote it to:
pi.cYou can compile and run with:
Here’s a tiny C program (single line in main) that prints π with n digits after the decimal point:
Compile and run:
This is very short, but note: precision is limited by long double (so it won’t give thousands of correct digits).
#include <stdio.h>#include <stdlib.h>#include <mpfr.h>
int main(int c,char**v){long n=c>1?atol(v[1]):100;mpfr_t p;mpfr_init2(p,(mpfr_prec_t)(n*3.3219280948873626)+64);mpfr_const_pi(p,MPFR_RNDN);mpfr_printf("%.*RNf\n",(int)n,p);mpfr_clear(p);}cc pi.c -lmpfr -lgmp -o pi./pi 1000#include <stdio.h>#include <stdlib.h>
static int next_pi_digit(int *a, int len) { long q = 0; for (int j = len; j > 0; --j) { long x = 10L * a[j - 1] + q * j; a[j - 1] = (int)(x % (2 * j - 1)); q = x / (2 * j - 1); } a[0] = (int)(q % 10); return (int)(q / 10);}
int main(int argc, char **argv) { int n = (argc > 1) ? atoi(argv[1]) : 100; // digits after decimal if (n < 0) return 1;
int total = n + 1; // include leading '3' int len = total * 10 / 3 + 1;
int *a = malloc((size_t)len * sizeof(int)); char *out = malloc((size_t)total); if (!a || !out) return 1;
for (int i = 0; i < len; ++i) a[i] = 2;
int out_len = 0, nines = 0; int predigit = next_pi_digit(a, len); // should become 3
for (int i = 1; i < total; ++i) { int d = next_pi_digit(a, len);
if (d == 9) { nines++; } else if (d == 10) { out[out_len++] = (char)('0' + predigit + 1); while (nines--) out[out_len++] = '0'; predigit = 0; nines = 0; } else { out[out_len++] = (char)('0' + predigit); while (nines--) out[out_len++] = '9'; predigit = d; nines = 0; } }
out[out_len++] = (char)('0' + predigit); while (nines--) out[out_len++] = '9';
putchar(out[0]); if (n > 0) putchar('.'); for (int i = 1; i < out_len; ++i) putchar(out[i]); putchar('\n');
free(a); free(out); return 0;}cc -O2 pi.c -o pi./pi 1000cc -O2 pi.c -o pi./pi 1000#include <stdio.h>#include <stdlib.h>#include <math.h>
int main(int c,char**v){int n=c>1?atoi(v[1]):10;printf("%.*Lf\n",n,acosl(-1.0L));}cc pi.c -lm -o pi./pi 20