YoushouldhavereceivedcopiesoftheGNUGeneralPublicLicenseandthe GNULesserGeneralPublicLicensealongwiththeGNUMPLibrary.Ifnot,
see https://www.gnu.org/licenses/. */
#include <string.h>
#include"gmp-impl.h" #include"longlong.h"
/*********************************************************/ /* Section sieve: sieving functions and tools for primes */ /*********************************************************/
staticunsigned
findnext_small (unsigned t, short diff)
{ /* For diff= 2, expect t = 1 if operand was negative. *Fordiff=-2,expectt>=3
*/
ASSERT (t >= 3 || (diff > 0 && t >= 1));
ASSERT (t < NP_SMALL_LIMIT);
/* Start from next candidate (2 or odd) */
t = diff > 0 ?
(t + 1) | (t != 1) :
((t - 2) | 1) + (t == 3);
for (; ; t += diff)
{ unsigned prime = 3; for (int i = 0; ; prime += primegap_small[i++])
{ unsigned q, r;
q = t / prime;
r = t - q * prime; /* r = t % prime; */ if (q < prime) return t; if (r == 0) break;
ASSERT (i < NUMBER_OF_PRIMES);
}
}
}
staticint
findnext (mpz_ptr p, unsignedlong(*negative_mod_ui)(const mpz_t, unsignedlong), void(*increment_ui)(mpz_t, const mpz_t, unsignedlong))
{ char *composite; constunsignedchar *primegap; unsignedlong prime_limit;
mp_size_t pn;
mp_bitcnt_t nbits; int i, m; unsigned odds_in_composite_sieve;
TMP_DECL;
/* sieve numbers up to sieve_limit and save prime count */
sieve_limit = calculate_sievelimit(nbits);
sieve = TMP_ALLOC_LIMBS (primesieve_size (sieve_limit));
prime_limit = gmp_primesieve(sieve, sieve_limit);
/* TODO: Storing (prime - last_prime)/2 would allow this to go uptothegap304599508537+514=304599509051.
With the current code our limit is 436273009+282=436273291 */
ASSERT (sieve_limit < 436273291); /* THINK: Memory used by both sieve and primegap_tmp is kept allocated,buttheymayoverlapifprimegapisfilledfrom largerdowntosmallerprimes...
*/
/* Needed to avoid assignment of read-only location */
primegap_tmp = TMP_ALLOC_TYPE (prime_limit, unsignedchar);
primegap = primegap_tmp;
i = 0;
last_prime = 3; /* THINK: should we get rid of sieve_limit and use (i < prime_limit)? */ for (mp_limb_t j = 4, *sp = sieve; j < sieve_limit; j += GMP_LIMB_BITS * 3) for (mp_limb_t b = j, x = ~ *(sp++); x != 0; b += 3, x >>= 1) if (x & 1)
{
mp_limb_t prime = b | 1;
primegap_tmp[i++] = prime - last_prime;
last_prime = prime;
}
/* Both primesieve and prime_limit ignore the first two primes. */
ASSERT(i == prime_limit);
}
if (nbits <= 32)
odds_in_composite_sieve = 336 / 2; elseif (nbits <= 64)
odds_in_composite_sieve = 1550 / 2; else /* Corresponds to a merit 14 prime_gap, which is rare. */
odds_in_composite_sieve = 5 * nbits;
/* composite[2*i] stores if p+2*i is a known composite */
composite = TMP_ALLOC_TYPE (odds_in_composite_sieve, char);
for (;;)
{ unsignedlong difference; unsignedlong incr, prime; int primetest;
memset (composite, 0, odds_in_composite_sieve);
prime = 3; for (i = 0; i < prime_limit; i++)
{ /* Distance to next multiple of prime */
m = negative_mod_ui(p, prime); /* Only care about odd multiplies of prime. */ if (m & 1)
m += prime;
m >>= 1;
/* Mark off any composites in sieve */ for (; m < odds_in_composite_sieve; m += prime)
composite[m] = 1;
prime += primegap[i];
}
difference = 0; for (incr = 0; incr < odds_in_composite_sieve; difference += 2, incr += 1)
{ if (composite[incr]) continue;
increment_ui(p, p, difference);
difference = 0;
/* Miller-Rabin test */
primetest = mpz_millerrabin (p, 25); if (primetest)
{
TMP_FREE; return primetest;
}
}
/* Sieve next segment, very rare */
increment_ui(p, p, difference);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.