@@ -60,7 +60,7 @@ This also provides a few functions unconnected to `PrimeSet`, which will be fast
60
60
case, but slower in the long term as they do not use any caching of primes.
61
61
62
62
*/
63
- #![ feature( core , step_by, test) ]
63
+ #![ feature( step_by, test) ]
64
64
#![ doc( html_root_url = "https://wackywendell.github.io/primes/" ) ]
65
65
66
66
#[ warn( non_camel_case_types) ]
@@ -70,25 +70,28 @@ case, but slower in the long term as they do not use any caching of primes.
70
70
#[ warn( missing_docs) ]
71
71
72
72
extern crate test;
73
+ extern crate num;
73
74
74
75
use std:: ops:: Index ;
75
76
use std:: slice;
76
- use std:: num:: { Float , cast} ;
77
77
use std:: cmp:: Ordering :: { Equal , Less , Greater } ;
78
+ use num:: { Float , NumCast } ;
78
79
79
80
#[ cfg( test) ]
80
81
use test:: Bencher ;
81
82
82
- fn sqrt_floor < T : std:: num:: NumCast > ( n : T ) -> T {
83
- cast :: < f64 , T > (
84
- ( cast :: < T , f64 > ( n) . unwrap ( ) ) . sqrt ( ) . floor ( )
85
- ) . unwrap ( )
83
+ /// Equivalent to floor(sqrt(n)), but takes an integer and returns an integer
84
+ fn sqrt_floor < T : NumCast > ( n : T ) -> T {
85
+ let n64 : f64 = NumCast :: from ( n) . unwrap ( ) ;
86
+ let rt = n64. sqrt ( ) . floor ( ) ;
87
+ NumCast :: from ( rt) . unwrap ( )
86
88
}
87
89
88
- fn sqrt_ceil < T : std:: num:: NumCast > ( n : T ) -> T {
89
- cast :: < f64 , T > (
90
- ( cast :: < T , f64 > ( n) . unwrap ( ) ) . sqrt ( ) . ceil ( )
91
- ) . unwrap ( )
90
+ /// Equivalent to floor(sqrt(n)), but takes an integer and returns an integer
91
+ fn sqrt_ceil < T : NumCast > ( n : T ) -> T {
92
+ let n64 : f64 = NumCast :: from ( n) . unwrap ( ) ;
93
+ let rt = n64. sqrt ( ) . ceil ( ) ;
94
+ NumCast :: from ( rt) . unwrap ( )
92
95
}
93
96
94
97
/** A prime generator, using the Sieve of Eratosthenes.
@@ -116,12 +119,11 @@ impl PrimeSet {
116
119
/// Finds one more prime, and adds it to the list
117
120
pub fn expand ( & mut self ) {
118
121
let mut l : u64 = self . lst [ self . lst . len ( ) -1 ] + 2 ;
119
- let mut sql = sqrt_floor ( l) ;
120
122
let mut remainder = 0 ;
121
123
loop {
122
124
for & n in self . lst . iter ( ) {
123
125
remainder = l % n;
124
- if remainder == 0 || n > sql {
126
+ if remainder == 0 || n* n > l {
125
127
break ;
126
128
}
127
129
} ;
@@ -132,7 +134,6 @@ impl PrimeSet {
132
134
} ;
133
135
134
136
l += 2 ;
135
- sql = sqrt_floor ( l) ;
136
137
}
137
138
}
138
139
@@ -227,22 +228,22 @@ impl PrimeSet {
227
228
pub fn prime_factors ( & mut self , n : u64 ) -> Vec < u64 > {
228
229
if n == 1 { return Vec :: new ( ) ; }
229
230
let mut curn = n;
230
- let mut m = sqrt_ceil ( curn) ;
231
231
let mut lst: Vec < u64 > = Vec :: new ( ) ;
232
232
for p in self . iter ( ) {
233
233
while curn % p == 0 {
234
+ println ! ( "Pushing {} ({} / {})" , p, curn, n) ;
234
235
lst. push ( p) ;
235
236
curn /= p;
236
237
if curn == 1 { return lst; }
237
- m = sqrt_ceil ( curn) ;
238
238
}
239
239
240
- if p > m {
241
- lst. push ( p) ;
240
+ if p* p > curn {
241
+ println ! ( "Final push {} ({} / {})" , p, curn, n) ;
242
+ lst. push ( curn) ;
242
243
return lst;
243
244
}
244
245
}
245
- panic ! ( "This should be unreachable." ) ;
246
+ unreachable ! ( "This should be unreachable." ) ;
246
247
}
247
248
}
248
249
@@ -272,9 +273,8 @@ impl<'a> Iterator for PrimeSetIter<'a> {
272
273
273
274
/// Find the first factor (other than 1) of a number
274
275
fn firstfac ( x : u64 ) -> u64 {
275
- let m = sqrt_ceil ( x) ;
276
276
if x % 2 == 0 { return 2 ; } ;
277
- for n in ( 3 ..m + 1 ) . step_by ( 2 ) {
277
+ for n in ( 3 ..) . step_by ( 2 ) . take_while ( |m| m * m <= x ) {
278
278
if x % n == 0 { return n; } ;
279
279
}
280
280
return x;
@@ -315,6 +315,30 @@ pub fn is_prime(n : u64) -> bool {
315
315
firstfac ( n) == n
316
316
}
317
317
318
+ #[ test]
319
+ fn test_sqrts ( ) {
320
+ assert_eq ! ( sqrt_ceil( 0 ) , 0 ) ;
321
+ assert_eq ! ( sqrt_floor( 0 ) , 0 ) ;
322
+
323
+ assert_eq ! ( sqrt_ceil( 1 ) , 1 ) ;
324
+ assert_eq ! ( sqrt_floor( 1 ) , 1 ) ;
325
+
326
+ let rts = [ 2u64 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 8734 , 809832 , 7433154 , 1 << 26 - 1 ] ;
327
+ for & rt in rts. iter ( ) {
328
+ let sq = rt * rt;
329
+ println ! ( "rt: {}, n: {}" , rt, sq) ;
330
+
331
+ assert_eq ! ( sqrt_ceil( sq) , rt) ;
332
+ assert_eq ! ( sqrt_floor( sq) , rt) ;
333
+
334
+ assert_eq ! ( sqrt_ceil( sq-1 ) , rt) ;
335
+ assert_eq ! ( sqrt_floor( sq-1 ) , rt-1 ) ;
336
+
337
+ assert_eq ! ( sqrt_ceil( sq+1 ) , rt+1 ) ;
338
+ assert_eq ! ( sqrt_floor( sq+1 ) , rt) ;
339
+ }
340
+ }
341
+
318
342
#[ test]
319
343
fn test_iter ( ) {
320
344
let mut pset = PrimeSet :: new ( ) ;
@@ -394,6 +418,7 @@ fn test_factors(){
394
418
395
419
// Test unique factors
396
420
for & ( n, ref v) in ns. iter ( ) {
421
+ println ! ( "{}: {:?}" , n, v) ;
397
422
assert_eq ! ( pset. prime_factors( n) , * v) ;
398
423
assert_eq ! ( factors( n) , * v) ;
399
424
0 commit comments