Files
print_hej/c/src/print_hej.c
T
Ein Anderssono 54d2fecee0 Initial commit: Pi calculation benchmark with 34 languages
- Added implementations for: bash, brainfuck, c, cpp, crystal, csharp, d, dart, elixir, erlang, fortran, go, haskell, java, javascript, julia, kotlin, objective-c, scala, typescript, lua, nim, odin, perl, php, python, r, ruby, rust, swift, zig, assembly, vimscript, wolfram
- All implementations use Machin's formula: π/4 = 4*arctan(1/5) - arctan(1/239)
- Build system with ./build.sh, test system with ./test.sh
- Performance testing with ./run_all.sh
- Comprehensive README.md explaining performance differences
- Test framework verifies correctness against known π values
2026-04-23 00:26:18 +02:00

120 lines
2.9 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmp.h>
// Calculate arctan(1/x) using Taylor series
// arctan(1/x) = 1/x - 1/(3*x^3) + 1/(5*x^5) - ...
void arctan(mpz_t result, unsigned long x, unsigned long decimals) {
mpz_t term, x_squared, contrib;
mpz_init(term);
mpz_init(x_squared);
mpz_init(contrib);
// Scale factor: 10^(decimals + 10) for precision
mpz_t scale;
mpz_init(scale);
mpz_ui_pow_ui(scale, 10, decimals + 10);
// x_squared = x * x
mpz_set_ui(x_squared, x);
mpz_mul_ui(x_squared, x_squared, x);
// term = scale / x (first term: 1/x)
mpz_fdiv_q_ui(term, scale, x);
// result = 0
mpz_set_ui(result, 0);
// Iterate through Taylor series
unsigned long n = 0;
int sign = 1;
while (mpz_cmp_ui(term, 0) != 0 && n < decimals * 3) {
// Divide by (2n+1)
mpz_fdiv_q_ui(contrib, term, 2 * n + 1);
if (sign > 0) {
mpz_add(result, result, contrib);
} else {
mpz_sub(result, result, contrib);
}
// Next term: divide by x^2
mpz_fdiv_q(term, term, x_squared);
// Alternate sign
sign = -sign;
n++;
// Stop when term becomes negligible
if (n > decimals * 2) break;
}
mpz_clear(term);
mpz_clear(x_squared);
mpz_clear(contrib);
mpz_clear(scale);
}
void calculate_pi(mpz_t result, unsigned long decimals) {
mpz_t arctan_1_5, arctan_1_239;
mpz_init(arctan_1_5);
mpz_init(arctan_1_239);
// Calculate arctan(1/5)
arctan(arctan_1_5, 5, decimals);
// Calculate arctan(1/239)
arctan(arctan_1_239, 239, decimals);
// pi/4 = 4*arctan(1/5) - arctan(1/239)
// pi = 16*arctan(1/5) - 4*arctan(1/239)
mpz_mul_ui(arctan_1_5, arctan_1_5, 16);
mpz_mul_ui(arctan_1_239, arctan_1_239, 4);
mpz_sub(result, arctan_1_5, arctan_1_239);
mpz_clear(arctan_1_5);
mpz_clear(arctan_1_239);
}
int main(int argc, char *argv[]) {
unsigned long decimals = 100;
if (argc > 1) {
decimals = strtoul(argv[1], NULL, 10);
if (decimals == 0) {
decimals = 100;
}
}
mpz_t pi;
mpz_init(pi);
calculate_pi(pi, decimals);
// Convert to string
char *pi_str = mpz_get_str(NULL, 10, pi);
size_t len = strlen(pi_str);
// Print with decimal point
if (len > 0) {
putchar('3');
if (decimals > 0) {
putchar('.');
// Print decimals, skipping the leading "3"
size_t start = 1;
size_t end = start + decimals;
if (end > len) end = len;
for (size_t i = start; i < end && i < len; i++) {
putchar(pi_str[i]);
}
}
putchar('\n');
}
free(pi_str);
mpz_clear(pi);
return 0;
}