Thanks to the people who provided the references for gmp.
My own (very simple) gmp-based Lucas-Lehmer program follows below:
I wrote it mostly in order to make sure I understood what mprime was doing,
especially the Res64.  As I mentionned, it is *WAY* slower than mprime,
even for primes far below 1,000,000.  This is not at all surprising,
of course, given the algorithm that gmp uses for multiplication.
Even if gmp had a faster algorithm, mprime would *still* be faster
since it was optimized in machine-language.

Oh, btw, this was done in Linux. It probably works anywhere you have
gmp and a C compiler, though.

==========================================================================

/*************************************************************************

lucaslehmer.c

Compute this program thus:

gcc lucaslehmer.c -lm -lgmp -O3 -Wall -o lucaslehmer

************************************************************************/

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>

unsigned long int p, i, j;
mpz_t pp, ll, aux;

int
main(int argc, char *argv[])
{
  extern unsigned long int p, i, j;
  extern mpz_t pp, ll, aux;
  int k;

  mpz_init(pp);
  mpz_init(ll);
  mpz_init(aux);

  if ( argc == 1 )
  {
    fprintf(stderr,"lucaslehmer: usage: lucaslehmer p1 p2 ... pn\n");
  }
  else for ( k = 1 ; k < argc ; k++ )
  {
    p = atol(argv[k]);

    mpz_set_ui(ll,(long)(4));
    mpz_ui_pow_ui(aux,(long)(2),p);
    mpz_sub_ui(pp,aux,(long)(1));

    for ( j = 1 ; j + 2 <= p ; j++ )
    {
      mpz_powm_ui(aux,ll,(long)(2),pp);
      mpz_sub_ui(ll,aux,(long)(2));
    }

    if ( mpz_sgn(ll) == 0 )
    {
      fprintf(stdout,"M%ld is a prime!\n",p);
    }
    else
    {
      mpz_fdiv_r_2exp(aux,ll,(long)(64));
      fprintf(stdout,"M%ld is not a prime. Res64: ",p);
      mpz_out_str(stdout,(int)(16),aux);
      fprintf(stdout,"\n");
    }
  }

  return(0);
}

Reply via email to