Skip to content

Instantly share code, notes, and snippets.

@quantumelixir
Created January 15, 2011 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quantumelixir/780935 to your computer and use it in GitHub Desktop.
Save quantumelixir/780935 to your computer and use it in GitHub Desktop.
Compute factorial of a given number using two different methods (uses GMP)
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>
#include <gmp.h>
long int NAIVE = 30;
typedef unsigned long int ulong;
mpz_t* mul_naive(ulong* array, ulong start, ulong end);
mpz_t* mul_split(ulong* array, ulong start, ulong end);
ulong* mul_init(ulong n);
mpz_t*
mul_naive(ulong* array, ulong start, ulong end)
{
mpz_t* temp = (mpz_t *) malloc(sizeof(mpz_t));
ulong i;
mpz_init(*temp);
mpz_set_ui(*temp, array[start]);
for(i = start + 1; i < end; i++)
mpz_mul_ui(*temp, *temp, array[i]);
return temp;
}
mpz_t*
mul_split(ulong* array, ulong start, ulong end)
{
mpz_t* temp = NULL;
mpz_t *m1, *m2;
if (start + 1 == end)
{
temp = (mpz_t *) malloc(sizeof(mpz_t));
mpz_init(*temp);
mpz_set_ui(*temp, array[start]);
return temp;
}
else if (end - start <= NAIVE)
return mul_naive(array, start, end);
temp = (mpz_t *) malloc(sizeof(mpz_t));
mpz_init(*temp);
m1 = mul_split(array, start, (start + end)>>1);
m2 = mul_split(array, (start + end)>>1, end);
mpz_mul(*temp, *m1, *m2);
mpz_clear(*m1);
mpz_clear(*m2);
return temp;
}
ulong*
mul_init(ulong n)
{
ulong i;
ulong* array = (ulong *) malloc(sizeof(ulong) * n);
for(i = 0; i < n; i++)
array[i] = i + 1;
return array;
}
int
main(int argc, char *argv[])
{
if (argc > 3 || argc < 2)
{
printf("Please specify an integer as the argument\n");
exit(1);
}
ulong n = atoi(argv[1]);
if (argc == 3)
NAIVE = atoi(argv[2]);
clock_t start, stop;
start = clock();
ulong* array = mul_init(n);
stop = clock();
printf("naiv:%lu ", NAIVE);
printf("init:%f ", (double)(stop - start)/CLOCKS_PER_SEC);
start = clock();
mpz_t* result = mul_split(array, 0, n);
stop = clock();
printf("calc:%f\n", (double)(stop - start)/CLOCKS_PER_SEC);
gmp_printf("%Zd\n", *result);
free(array);
mpz_clear(*result);
return 0;
}
// gcc -I/usr/include/malloc/ -L/opt/local/lib/ -lgmp factorial.c -o factorial
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment