示例#1
0
文件: nbtheory.cpp 项目: vgck/opendr2
bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod)
{
	assert(!equiv.IsNegative() && equiv < mod);

	Integer gcd = GCD(equiv, mod);
	if (gcd != Integer::One())
	{
		// the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv)
		if (p <= gcd && gcd <= max && IsPrime(gcd))
		{
			p = gcd;
			return true;
		}
		else
			return false;
	}

	BuildPrimeTable();

	if (p <= primeTable[primeTableSize-1])
	{
		word *pItr;

		--p;
		if (p.IsPositive())
			pItr = std::upper_bound(primeTable, primeTable+primeTableSize, p.ConvertToLong());
		else
			pItr = primeTable;

		while (pItr < primeTable+primeTableSize && *pItr%mod != equiv)
			++pItr;

		if (pItr < primeTable+primeTableSize)
		{
			p = *pItr;
			return p <= max;
		}

		p = primeTable[primeTableSize-1]+1;
	}

	assert(p > primeTable[primeTableSize-1]);

	if (mod.IsOdd())
		return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1);

	p += (equiv-p)%mod;

	if (p>max)
		return false;

	PrimeSieve sieve(p, max, mod);

	while (sieve.NextCandidate(p))
	{
		if (FastProbablePrimeTest(p) && IsPrime(p))
			return true;
	}

	return false;
}
示例#2
0
bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector)
{
	assert(!equiv.IsNegative() && equiv < mod);

	Integer gcd = GCD(equiv, mod);
	if (gcd != Integer::One())
	{
		// the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv)
		if (p <= gcd && gcd <= max && IsPrime(gcd) && (!pSelector || pSelector->IsAcceptable(gcd)))
		{
			p = gcd;
			return true;
		}
		else
			return false;
	}

	unsigned int primeTableSize;
	const word16 * primeTable = GetPrimeTable(primeTableSize);

	if (p <= primeTable[primeTableSize-1])
	{
		const word16 *pItr;

		--p;
		if (p.IsPositive())
			pItr = std::upper_bound(primeTable, primeTable+primeTableSize, (word)p.ConvertToLong());
		else
			pItr = primeTable;

		while (pItr < primeTable+primeTableSize && !(*pItr%mod == equiv && (!pSelector || pSelector->IsAcceptable(*pItr))))
			++pItr;

		if (pItr < primeTable+primeTableSize)
		{
			p = *pItr;
			return p <= max;
		}

		p = primeTable[primeTableSize-1]+1;
	}

	assert(p > primeTable[primeTableSize-1]);

	if (mod.IsOdd())
		return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1, pSelector);

	p += (equiv-p)%mod;

	if (p>max)
		return false;

	PrimeSieve sieve(p, max, mod);

	while (sieve.NextCandidate(p))
	{
		if ((!pSelector || pSelector->IsAcceptable(p)) && FastProbablePrimeTest(p) && IsPrime(p))
			return true;
	}

	return false;
}