Skip to content

Instantly share code, notes, and snippets.

@mrklein
Created May 5, 2013 14:52
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 mrklein/5521029 to your computer and use it in GitHub Desktop.
Save mrklein/5521029 to your computer and use it in GitHub Desktop.
Calculation of factorial and sum of number digits with GMP. Timing implemented for OS X.
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <mach/mach_time.h>
#include <gmp.h>
void factorial(mpz_t n, mpz_t res)
{
mpz_t unit, zero, cnt;
mpz_init_set_ui (unit, 1);
mpz_init_set_ui (zero, 0);
mpz_init_set_ui (cnt, 1);
mpz_set (res, unit);
while(mpz_cmp (cnt, n) <= 0) {
mpz_mul (res, res, cnt);
mpz_add (cnt, cnt, unit);
}
}
unsigned long sum_digits(mpz_t n)
{
unsigned long ret = 0, i_cnt;
char *t = mpz_get_str(NULL, 10, n);
for(i_cnt = 0; i_cnt < strlen(t); ++i_cnt) {
ret += (unsigned long) (t[i_cnt] - '0');
}
return ret;
}
void do_calc(void)
{
unsigned long nums[] = {1, 12, 123, 1234, 12345, 123456};
unsigned int lim = sizeof(nums) / sizeof(unsigned long);
unsigned long i_cnt, ret = 0;
for(i_cnt = 0; i_cnt < lim; ++i_cnt) {
mpz_t a, b;
mpz_init_set_ui (a, nums[i_cnt]);
mpz_init (b);
factorial (a, b);
ret += sum_digits(b);
}
printf("%lu\n", ret);
}
double time_it(void (*func)(void), int n) {
double total_duration;
mach_timebase_info_data_t info;
mach_timebase_info(&info);
uint64_t start;
uint64_t duration;
int i;
for(i = 0; i < n; ++i) {
start = mach_absolute_time();
func();
duration = mach_absolute_time() - start;
duration *= info.numer;
duration /= info.denom;
total_duration += duration;
}
return total_duration / 1e9 / n;
}
int main(int argc, char *argv[])
{
printf("Elapsed time: %f s\n", time_it(do_calc, 10));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment