[libmath-prime-util-perl] 19/55: forcomposites, edge cases and performance
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:53:40 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.41
in repository libmath-prime-util-perl.
commit cd7a0ea6532ce66b67a287e696ef3c1398253513
Author: Dana Jacobsen <dana at acm.org>
Date: Fri May 2 14:59:38 2014 -0700
forcomposites, edge cases and performance
---
Changes | 2 ++
XS.xs | 63 +++++++++++++++++++++++++++++++++++++++------------------------
2 files changed, 41 insertions(+), 24 deletions(-)
diff --git a/Changes b/Changes
index 5b377b2..92fa57a 100644
--- a/Changes
+++ b/Changes
@@ -23,6 +23,8 @@ Revision history for Perl module Math::Prime::Util
- Loosen requirements of lucas_sequence. More useful for general seqs.
Add tests for some common sequences.
+ - forcomposites handles beg and end near ~0.
+
0.40 2014-04-21
diff --git a/XS.xs b/XS.xs
index 77d4dbd..9960fde 100644
--- a/XS.xs
+++ b/XS.xs
@@ -1101,40 +1101,55 @@ forcomposites (SV* block, IN SV* svbeg, IN SV* svend = 0)
svarg = newSVuv(0);
GvSV(PL_defgv) = svarg;
#if USE_MULTICALL
- if (!CvISXSUB(cv) && (end-beg) > 200) {
+ if (!CvISXSUB(cv) && end >= beg) {
unsigned char* segment;
UV seg_base, seg_low, seg_high, c, cbeg, cend, prevprime, nextprime;
void* ctx;
dMULTICALL;
I32 gimme = G_VOID;
PUSH_MULTICALL(cv);
- if (beg <= 4) { /* sieve starts at 7, so handle this here */
- sv_setuv(svarg, 4); MULTICALL;
- beg = 6;
- }
- /* Find the two primes that bound their interval. */
- /* If beg or end are >= max_prime, then this will die. */
- prevprime = prev_prime(beg);
- nextprime = (end >= MPU_MAX_PRIME) ? MPU_MAX_PRIME : next_prime(end);
- ctx = start_segment_primes(beg, nextprime, &segment);
- while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) {
- START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_low - seg_base, seg_high - seg_base ) {
- cbeg = prevprime+1; if (cbeg < beg) cbeg = beg;
- prevprime = seg_base + p;
- cend = prevprime-1; if (cend > end) cend = end;
- for (c = cbeg; c <= cend; c++) {
- sv_setuv(svarg, c); MULTICALL;
- }
- } END_DO_FOR_EACH_SIEVE_PRIME
+ if (beg >= MPU_MAX_PRIME ||
+#if BITS_PER_WORD == 64
+ (beg >= UVCONST( 100000000000000) && end-beg < 120000) ||
+ (beg >= UVCONST( 10000000000000) && end-beg < 50000) ||
+ (beg >= UVCONST( 1000000000000) && end-beg < 20000) ||
+#endif
+ end-beg < 1000 ) {
+ beg = (beg <= 4) ? 3 : beg-1;
+ nextprime = next_prime(beg);
+ while (beg++ < end) {
+ if (beg == nextprime) nextprime = next_prime(beg);
+ else { sv_setuv(svarg, beg); MULTICALL; }
+ }
+ } else {
+ if (beg <= 4) { /* sieve starts at 7, so handle this here */
+ sv_setuv(svarg, 4); MULTICALL;
+ beg = 6;
+ }
+ /* Find the two primes that bound their interval. */
+ /* beg must be < max_prime, and end >= max_prime is special. */
+ prevprime = prev_prime(beg);
+ nextprime = (end >= MPU_MAX_PRIME) ? MPU_MAX_PRIME : next_prime(end);
+ ctx = start_segment_primes(beg, nextprime, &segment);
+ while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) {
+ START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_low - seg_base, seg_high - seg_base ) {
+ cbeg = prevprime+1; if (cbeg < beg) cbeg = beg;
+ prevprime = seg_base + p;
+ cend = prevprime-1; if (cend > end) cend = end;
+ for (c = cbeg; c <= cend; c++) {
+ sv_setuv(svarg, c); MULTICALL;
+ }
+ } END_DO_FOR_EACH_SIEVE_PRIME
+ }
+ end_segment_primes(ctx);
+ if (end > nextprime) /* Complete the case where end > max_prime */
+ while (nextprime++ < end)
+ { sv_setuv(svarg, nextprime); MULTICALL; }
}
- end_segment_primes(ctx);
- beg = nextprime + 1;
- if (beg != MPU_MAX_PRIME+1)
- MPUassert( beg >= end, "composite sieve skipped end numbers" );
FIX_MULTICALL_REFCOUNT;
POP_MULTICALL;
}
- /* Fall through to handle the edge case */
+ else
#endif
if (beg <= end) {
beg = (beg <= 4) ? 3 : beg-1;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git
More information about the Pkg-perl-cvs-commits
mailing list