Thursday, January 2, 2014

Project Euler Problem 448 and the GMP Library: Part 2

Below is prototypical program that uses the gmp.h interface to compute the product of two very large numbers. According to the documentation, you have to both declare and initialize a variable before you can use it.
#include < stdio.h >
#include <stdlib.h>
#include <gmp.h>
 
int main(void)
{
/*gmp variable declarations*/
 mpz_t x;
 mpz_t y;
 mpz_t result;
 
/*variable initializations*/
 mpz_init(x);/*make room for x*/
 mpz_init(y);
 mpz_init(result);
 /* these functions are the equivalent of variable assignments; note
    the extra parameter 10 stands for radix, or base*/
 mpz_set_str(x, "7612058254738945", 10);/* this says x holds a big base 10 integer*/
 mpz_set_str(y, "9263591128439081", 10);
 
/*this function is where the actual computation takes place:
  it stores x*y in result*/
 mpz_mul(result, x, y);
/* this function is the gmp extension of the standard printf function
the format specifier is Zd which we can take to mean big int*/
 gmp_printf("\n    %Zd\n*\n    %Zd\n--------------------\n%Zd\n\n", x, y, result);
 
 /* free used memory */
 mpz_clear(x);
 mpz_clear(y);
 mpz_clear(result);
 return EXIT_SUCCESS;
}
Notice how complicated this was. This program really doesn't do anything at all interesting. All you can take from this is that interacting with the gmp library requires a lot of boiler plate. If that was uninteresting let's do something a little interesting: the factorial function.
#include < stdio.h >
#include <stdlib.h>
#include <gmp.h>
#include <assert.h>
 
void fact(int n){
  int i;
  mpz_t fact;
 /*this is a convenient function that helps avoid some of that
    boiler plate: it both declares and initializes in one step*/
  mpz_init_set_ui(fact,1); /* fact = 1 */
  for (i=1; i <= n ; ++i){
    mpz_mul_ui(fact,fact,i); /* fact = fact * i */
  }
  
  gmp_printf ("%d!= %Zd ",n,fact);
  mpz_clear(fact);
 
}
 
int main(int argc, char * argv[]){
  int n;
 
 
  if (argc <= 1){
    printf ("Usage: %s <number> \n", argv[0]);
    return 2;
  }
 
  n = atoi(argv[1]);/*convert commandline arg to int*/
  assert( n >= 0);/*check operation success*/
  fact(n);
 
 
  return 0;
}
Next post, I will test the lcm functions in the gmp library and finally get that solution.