YoushouldhavereceivedcopiesoftheGNUGeneralPublicLicenseandthe GNULesserGeneralPublicLicensealongwiththeGNUMPLibrary.Ifnot,
see https://www.gnu.org/licenses/. */
#include"gmp-impl.h" #include"longlong.h"
staticint isprime (unsignedlongint);
/* MPN_MOD_OR_MODEXACT_1_ODD can be used instead of mpn_mod_1 for the trial division.Itgivesaresultwhichisnottheactualremainderrbuta valuecongruenttor*2^nmodd.Sincealltheprimesbeingtestedare
odd, r*2^n mod p will be 0 if and only if r mod p is 0. */
int
mpz_probab_prime_p (mpz_srcptr n, int reps)
{
mp_limb_t r;
mpz_t n2;
/* Handle small and negative n. */ if (mpz_cmp_ui (n, 1000000L) <= 0)
{ if (mpz_cmpabs_ui (n, 1000000L) <= 0)
{ int is_prime; unsignedlong n0;
n0 = mpz_get_ui (n);
is_prime = n0 & (n0 > 1) ? isprime (n0) : n0 == 2; return is_prime ? 2 : 0;
} /* Negative number. Negate and fall out. */
PTR(n2) = PTR(n);
SIZ(n2) = -SIZ(n);
n = n2;
}
/* If n is now even, it is not a prime. */ if (mpz_even_p (n)) return0;
#ifdefined (PP) /* Check if n has small factors. */ #ifdefined (PP_INVERTED)
r = MPN_MOD_OR_PREINV_MOD_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP,
(mp_limb_t) PP_INVERTED); #else
r = mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP); #endif if (r % 3 == 0 #if GMP_LIMB_BITS >= 4
|| r % 5 == 0 #endif #if GMP_LIMB_BITS >= 8
|| r % 7 == 0 #endif #if GMP_LIMB_BITS >= 16
|| r % 11 == 0 || r % 13 == 0 #endif #if GMP_LIMB_BITS >= 32
|| r % 17 == 0 || r % 19 == 0 || r % 23 == 0 || r % 29 == 0 #endif #if GMP_LIMB_BITS >= 64
|| r % 31 == 0 || r % 37 == 0 || r % 41 == 0 || r % 43 == 0
|| r % 47 == 0 || r % 53 == 0 #endif
)
{ return0;
} #endif/* PP */
/* Do more dividing. We collect small primes, using umul_ppmm, until we overflowasinglelimb.Wedivideournumberbythesmallprimesproduct,
and look for factors in the remainder. */
{ unsignedlongint ln2; unsignedlongint q;
mp_limb_t p1, p0, p; unsignedint primes[15]; int nprimes;
nprimes = 0;
p = 1;
ln2 = mpz_sizeinbase (n, 2); /* FIXME: tune this limit */ for (q = PP_FIRST_OMITTED; q < ln2; q += 2)
{ if (isprime (q))
{
umul_ppmm (p1, p0, p, q); if (p1 != 0)
{
r = MPN_MOD_OR_MODEXACT_1_ODD (PTR(n), (mp_size_t) SIZ(n), p); while (--nprimes >= 0) if (r % primes[nprimes] == 0)
{
ASSERT_ALWAYS (mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) primes[nprimes]) == 0); return0;
}
p = q;
nprimes = 0;
} else
{
p = p0;
}
primes[nprimes++] = q;
}
}
}
/* Perform a number of Miller-Rabin tests. */ return mpz_millerrabin (n, reps);
}
staticint
isprime (unsignedlongint t)
{ unsignedlongint q, r, d;
ASSERT (t >= 3 && (t & 1) != 0);
d = 3; do {
q = t / d;
r = t - q * d; if (q < d) return1;
d += 2;
} while (r != 0); return0;
}
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.