prime_sieve
    Marco Bodrato 
    bodrato at mail.dm.unipi.it
       
    Sun Jan  3 14:58:07 UTC 2016
    
    
  
Ciao,
Il Dom, 3 Gennaio 2016 3:42 pm, Marco Bodrato ha scritto:
> I attach the code.
The list does not like my attachments...
-----8<-----------8<----------
/* gmp_numberofprimesupto_ui (N) -- Returns the number the primes in
   the range [0..N].
   gmp_prime_sieve (S, E, *c, F) -- Calls F(c,p) for each prime p in
   the range [S..E]; when the range is over or F returns a non-zero
   value, it returns the number of used primes.
THE FUNCTION IN THIS FILE USE INTERNAL FUNCTIONS OF GMP, WITH A
MUTABLE INTERFACE.  IT WAS ONLY TESTED WITH GMP-6.1; IT IS ALMOST
GUARANTEED THAT IT WILL NOT WORK WITH A FUTURE GNU MP RELEASE.
Copyright 2012, 2015, 2016 Marco Bodrato.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
see https://www.gnu.org/licenses/.  */
#include "gmp.h"
#include "gmp-impl.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*********************************************************/
/* Section sieve: sieving functions and tools for primes */
/*********************************************************/
static mp_limb_t
n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; }
/* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/
static mp_limb_t
id_to_n  (mp_limb_t id)  { return id*3+1+(id&1); }
static mp_size_t
primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; }
/*************************************************************/
/* Section macros: common macros, for swing/fac/bin (&sieve) */
/*************************************************************/
#define LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)			\
    __max_i = (end);						\
								\
    do {							\
      ++__i;							\
      if (((sieve)[__index] & __mask) == 0)			\
	{							\
          mp_limb_t prime;					\
	  prime = id_to_n(__i)
#define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve)		\
  do {								\
    mp_limb_t __mask, __index, __max_i, __i;			\
								\
    __i = (start)-(off);					\
    __index = __i / GMP_LIMB_BITS;				\
    __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS);		\
    __i += (off);						\
								\
    LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)
#define LOOP_ON_SIEVE_STOP					\
	}							\
      __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1);	\
      __index += __mask & 1;					\
    }  while (__i <= __max_i)
#define LOOP_ON_SIEVE_END					\
    LOOP_ON_SIEVE_STOP;						\
  } while (0)
typedef int prime_callback_func (void *ctx, unsigned long prime);
unsigned long
gmp_prime_sieve (unsigned long start, unsigned long end,
		 void *ctx, prime_callback_func *f)
{
  unsigned long ret;
  ret = (start <= 2) & (2 <= end);
  if ((ret) && (*f) (ctx, 2))
    return 1;
  if ((start <= 3) & (3 <= end))
    {
      ++ret;
      if ((*f) (ctx, 3))
	return ret;
    }
  if (end > 4)
    {
      mp_limb_t *sieve;
      mp_size_t size;
      size = primesieve_size (end);
      sieve = __GMP_ALLOCATE_FUNC_LIMBS (size);
      gmp_primesieve (sieve, end);
      start = MAX (start, 5) | 1;
      LOOP_ON_SIEVE_BEGIN (prime, n_to_bit(start) + (start % 3 == 0),
n_to_bit (end), 0, sieve);
      ++ret;
      if ((*f) (ctx, prime)) break;
      LOOP_ON_SIEVE_END;
      __GMP_FREE_FUNC_LIMBS (sieve, size);
    }
  return ret;
}
unsigned long
gmp_numberofprimesupto_ui (unsigned long n)
{
  static const unsigned table[] = { 0, 0, 1, 2, 2 };
  if (n < numberof (table))
    return table[n];
  else
    {
      mp_limb_t *sieve;
      mp_size_t size;
      unsigned int ret;
      size = primesieve_size (n);
      sieve = __GMP_ALLOCATE_FUNC_LIMBS (size);
      ret = gmp_primesieve (sieve, n);
      __GMP_FREE_FUNC_LIMBS (sieve, size);
      return table[numberof (table)-1] + ret;
    }
}
#ifdef MAIN
int
count3mod4 (void *ctx, unsigned long prime)
{
  *(unsigned long*) ctx += (prime > 2) & (prime >> 1);
  return 0;
}
int
main (int argc, char *argv[])
{
  unsigned long s, N, c;
  s = 0;
  N = strtoul (argv[1], NULL, 0);
  if (argc > 2)
    {
      s = N;
      N = strtoul (argv[2], NULL, 0);
    }
  c = 0;
  printf ("pi(%lu .. %lu)=%lu\n", s, N, gmp_prime_sieve (s, N, &c,
&count3mod4));
  printf ("pi(%lu .. %lu,=3 mod 4)=%lu\n", s, N, c);
  return 0;
}
#endif
#ifdef MAINPI
int
main (int argc, char *argv[])
{
  unsigned long N;
  N = strtoul (argv[1], NULL, 0);
  printf ("pi(0 .. %lu)=%lu\n", N, gmp_numberofprimesupto_ui (N));
  return 0;
}
#endif
-----8<-----------8<----------
-- 
http://bodrato.it/
    
    
More information about the gmp-discuss
mailing list