bool find_init_composite_pos(int prime, int residue, int& pos1, int& pos2){ int rd2 = residue; if(residue > prime || residue < 0) rd2 = residue % prime; if(rd2 < 0) rd2 +=prime; i64 nonres = find_non_residue(prime); i64 r = Tonelli_Shanks(prime, nonres, rd2); i64 r2 = prime - r; if( r == NOT_FOUND) return false; int coeff = simpleEq( r, prime) ; assert((coeff * prime + r )%10 ==0); pos1 = (coeff * prime + r)/ 10; if(100LL*pos1*pos1 + prime - residue == prime) pos1 += prime; coeff = simpleEq( r2, prime); assert((coeff * prime + r2 )%10 ==0); pos2 = (coeff * prime + r2)/ 10; if(100LL*pos2*pos2 + prime - residue == prime) pos2 += prime; return true; }
void Sieve::CalculateOffsets2(void) { if (factorbase.size() == 0) return; if (Q(0) % 2 == 0) { OffsetValue off2(0, 2, std::log(2.0)); offsets.push_back(off2); CalculateOffsetsRec(0, 2, 2, std::log(2.0)); } else { OffsetValue off2(1, 2, std::log(2.0)); offsets.push_back(off2); CalculateOffsetsRec(1, 2, 2, std::log(2.0)); } for (std::vector<unsigned long int>::iterator it = factorbase.begin() + 1; it != factorbase.end(); ++it) { mpz_class retv = Tonelli_Shanks(*it, N); mpz_class cof = *it - retv; retv = (retv - N_sqrt) % *it; if (retv < 0) retv += *it; cof = (cof - N_sqrt) % *it; if (cof < 0) cof += *it; if (retv < SIEVESIZE && retv >= 0) { OffsetValue off(retv.get_ui(), *it, std::log((float)*it)); offsets.push_back(off); CalculateOffsetsRec(retv.get_ui(), *it, *it, std::log((float)*it)); } if (cof < SIEVESIZE && cof >= 0) { OffsetValue off(cof.get_ui(), *it, std::log((float)*it)); offsets.push_back(off); CalculateOffsetsRec(cof.get_ui(), *it, *it, std::log((float)*it)); } } }