diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-04-10 11:47:48 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-04-10 11:47:48 +0200 |
commit | 4908c79a018cdea41d2899ebcef59831117a07cd (patch) | |
tree | 9597ce58bf51c045b135ba6f11e5723dc3f682ad /coreutils | |
parent | f428f1dc6cb9e9d3cfcfe3c555d44b6a7686cc88 (diff) | |
download | busybox-w32-4908c79a018cdea41d2899ebcef59831117a07cd.tar.gz busybox-w32-4908c79a018cdea41d2899ebcef59831117a07cd.tar.bz2 busybox-w32-4908c79a018cdea41d2899ebcef59831117a07cd.zip |
factor: better comments, slightl more clever conversion even->odd
function old new delta
isqrt_odd 114 111 -3
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/factor.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/coreutils/factor.c b/coreutils/factor.c index 5c4d124a8..aa2f63089 100644 --- a/coreutils/factor.c +++ b/coreutils/factor.c | |||
@@ -86,8 +86,9 @@ static inline half_t isqrt(wide_t N) | |||
86 | static NOINLINE half_t isqrt_odd(wide_t N) | 86 | static NOINLINE half_t isqrt_odd(wide_t N) |
87 | { | 87 | { |
88 | half_t s = isqrt(N); | 88 | half_t s = isqrt(N); |
89 | if (s && !(s & 1)) /* even? */ | 89 | /* Subtract 1 from even s, odd s won't change: */ |
90 | s--; | 90 | /* (doesnt work for zero, but we know that s != 0 here) */ |
91 | s = (s - 1) | 1; | ||
91 | return s; | 92 | return s; |
92 | } | 93 | } |
93 | 94 | ||
@@ -107,6 +108,16 @@ static NOINLINE void factorize(wide_t N) | |||
107 | N >>= 1; | 108 | N >>= 1; |
108 | } | 109 | } |
109 | 110 | ||
111 | /* The code needs to be optimized for the case where | ||
112 | * there are large prime factors. For example, | ||
113 | * this is not hard: | ||
114 | * 8262075252869367027 = 3 7 17 23 47 101 113 127 131 137 823 | ||
115 | * (the largest factor to test is only ~sqrt(823) = 28) | ||
116 | * but this is: | ||
117 | * 18446744073709551601 = 53 348051774975651917 | ||
118 | * the last factor requires testing up to | ||
119 | * 589959129 - about 100 million iterations. | ||
120 | */ | ||
110 | max_factor = isqrt_odd(N); | 121 | max_factor = isqrt_odd(N); |
111 | count3 = 3; | 122 | count3 = 3; |
112 | count5 = 6; | 123 | count5 = 6; |
@@ -130,18 +141,28 @@ static NOINLINE void factorize(wide_t N) | |||
130 | * 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47... | 141 | * 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47... |
131 | * ^ ^ ^ ^ ^ ^ ^ _ ^ ^ _ ^ ^ ^ ^ | 142 | * ^ ^ ^ ^ ^ ^ ^ _ ^ ^ _ ^ ^ ^ ^ |
132 | * (^ = primes, _ = would-be-primes-if-not-divisible-by-5) | 143 | * (^ = primes, _ = would-be-primes-if-not-divisible-by-5) |
144 | * The numbers with space under them are excluded by sieve 3. | ||
133 | */ | 145 | */ |
134 | count7--; | 146 | count7--; |
135 | count5--; | 147 | count5--; |
136 | count3--; | 148 | count3--; |
137 | if (count3 && count5 && count7) | 149 | if (count3 && count5 && count7) |
138 | continue; | 150 | continue; |
139 | if (count3 == 0) | 151 | /* |
152 | * "factor" is multiple of 3 33% of the time (count3 reached 0), | ||
153 | * else, multiple of 5 13% of the time, | ||
154 | * else, multiple of 7 7.6% of the time. | ||
155 | * Cumulatively, with 3,5,7 sieving we are here 54.3% of the time. | ||
156 | */ | ||
157 | if (count3 == 0) { | ||
140 | count3 = 3; | 158 | count3 = 3; |
141 | if (count5 == 0) | 159 | } |
160 | if (count5 == 0) { | ||
142 | count5 = 5; | 161 | count5 = 5; |
143 | if (count7 == 0) | 162 | } |
163 | if (count7 == 0) { | ||
144 | count7 = 7; | 164 | count7 = 7; |
165 | } | ||
145 | goto next_factor; | 166 | goto next_factor; |
146 | } | 167 | } |
147 | end: | 168 | end: |