11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4+ using System . Numerics ;
45
56namespace Open . Numeric . Primes
67{
@@ -43,6 +44,24 @@ static bool IsPrimeInternal(ulong value)
4344 return true ;
4445 }
4546
47+ static bool IsPrimeInternal ( BigInteger value )
48+ {
49+ BigInteger divisor = 6 ;
50+ while ( divisor * divisor - 2 * divisor + 1 <= value )
51+ {
52+
53+ if ( value % ( divisor - 1 ) == 0 )
54+ return false ;
55+
56+ if ( value % ( divisor + 1 ) == 0 )
57+ return false ;
58+
59+ divisor += 6 ;
60+ }
61+
62+ return true ;
63+ }
64+
4665 /// <summary>
4766 /// Validates if a number is prime.
4867 /// </summary>
@@ -69,6 +88,24 @@ public static bool IsPrime(ulong value)
6988
7089 }
7190
91+ /// <summary>
92+ /// Validates if a number is prime.
93+ /// </summary>
94+ /// <param name="value">Value to verify.</param>
95+ /// <returns>True if the provided value is a prime number</returns>
96+ public static bool IsPrime ( BigInteger value )
97+ {
98+ value = BigInteger . Abs ( value ) ;
99+ if ( value == 0 || value == 1 )
100+ return false ;
101+ if ( value == 2 || value == 3 )
102+ return true ;
103+
104+ return value % 2 != 0
105+ && value % 3 != 0
106+ && IsPrimeInternal ( value ) ;
107+ }
108+
72109 /// <summary>
73110 /// Validates if a number is prime.
74111 /// </summary>
@@ -79,13 +116,28 @@ public static bool IsPrime(long value)
79116 return IsPrime ( ( ulong ) Math . Abs ( value ) ) ;
80117 }
81118
119+ /// <summary>
120+ /// Validates if a number is prime.
121+ /// </summary>
122+ /// <param name="value">Value to verify.</param>
123+ /// <returns>True if the provided value is a prime number</returns>
82124 public static bool IsPrime ( double value )
83125 {
84- return ( Math . Floor ( value ) == value )
85- ? IsPrime ( ( long ) value )
86- : false ;
126+ if ( Math . Floor ( value ) != value )
127+ return false ;
128+
129+ value = Math . Abs ( value ) ;
130+ if ( value <= ulong . MaxValue )
131+ return IsPrime ( ( ulong ) value ) ;
132+
133+ return IsPrime ( ( BigInteger ) value ) ;
87134 }
88135
136+ /// <summary>
137+ /// Iterates the prime multiples of the provided value.
138+ /// </summary>
139+ /// <param name="value">Value to verify.</param>
140+ /// <returns>An enumerable that contains the multiples of the provided value.</returns>
89141 public static IEnumerable < ulong > MultiplesOf ( ulong value )
90142 {
91143 ulong last = 1 ;
@@ -112,39 +164,77 @@ public static class Prime
112164
113165 internal static IEnumerable < ulong > ValidPrimeTests ( ulong staringAt = 2 )
114166 {
115- if ( staringAt > 2 )
167+ var n = staringAt ;
168+ if ( n > 2 )
116169 {
117- if ( staringAt % 2 == 0 )
118- staringAt ++ ;
170+ if ( n % 2 == 0 )
171+ n ++ ;
119172 }
173+ else
120174 {
121175 yield return 2 ;
122- staringAt = 3 ;
176+ n = 3 ;
123177 }
124178
125- for ( ulong n = staringAt ; n < ulong . MaxValue - 1 ; n += 2 )
179+ for ( ; n < ulong . MaxValue - 1 ; n += 2 )
126180 yield return n ;
127181 }
128182
129- internal static IEnumerable < long > ValidPrimeTests ( long staringAt = 2 )
183+ internal static IEnumerable < long > ValidPrimeTests ( long staringAt )
130184 {
131185 var sign = staringAt < 0 ? - 1 : 1 ;
132- staringAt = Math . Abs ( staringAt ) ;
186+ var n = Math . Abs ( staringAt ) ;
133187
134- if ( staringAt > 2 )
188+ if ( n > 2 )
135189 {
136- if ( staringAt % 2 == 0 )
137- staringAt ++ ;
190+ if ( n % 2 == 0 )
191+ n ++ ;
138192 }
193+ else
139194 {
140195 yield return sign * 2 ;
141- staringAt = 3 ;
196+ n = 3 ;
142197 }
143198
144- for ( long n = staringAt ; n < long . MaxValue - 1 ; n += 2 )
199+ for ( ; n < long . MaxValue - 1 ; n += 2 )
145200 yield return sign * n ;
146201 }
147202
203+ internal static IEnumerable < BigInteger > ValidPrimeTests ( BigInteger staringAt )
204+ {
205+ var sign = staringAt . Sign ;
206+ if ( sign == 0 ) sign = 1 ;
207+ var n = BigInteger . Abs ( staringAt ) ;
208+
209+ if ( n > 2 )
210+ {
211+ if ( n % 2 == 0 )
212+ n ++ ;
213+ }
214+ else
215+ {
216+ yield return sign * 2 ;
217+ n = 3 ;
218+ }
219+
220+ while ( true )
221+ {
222+ yield return sign * n ;
223+ n += 2 ;
224+ }
225+ }
226+
227+ /// <summary>
228+ /// Returns an enumerable that will iterate every prime starting at the starting value.
229+ /// </summary>
230+ /// <param name="staringAt">Allows for skipping ahead any integer before checking for inclusive and subsequent primes.</param>
231+ /// <returns></returns>
232+ public static IEnumerable < BigInteger > Numbers ( BigInteger staringAt )
233+ {
234+ return ValidPrimeTests ( staringAt )
235+ . Where ( v => Number . IsPrime ( v ) ) ;
236+ }
237+
148238 /// <summary>
149239 /// Returns an enumerable that will iterate every prime starting at the starting value.
150240 /// </summary>
@@ -184,6 +274,23 @@ public static ParallelQuery<ulong> NumbersInParallel(ulong staringAt = 2, ushort
184274 return tests . Where ( v => Number . IsPrime ( v ) ) ;
185275 }
186276
277+ /// <summary>
278+ /// Returns a parallel enumerable that will iterate every prime starting at the starting value.
279+ /// </summary>
280+ /// <param name="staringAt">Allows for skipping ahead any integer before checking for inclusive and subsequent primes.</param>
281+ /// <param name="degreeOfParallelism">Operates in parallel unless 1 is specified.</param>
282+ /// <returns></returns>
283+ public static ParallelQuery < BigInteger > NumbersInParallel ( BigInteger staringAt , ushort ? degreeOfParallelism = null )
284+ {
285+ var tests = ValidPrimeTests ( staringAt )
286+ . AsParallel ( ) . AsOrdered ( ) ;
287+
288+ if ( degreeOfParallelism . HasValue )
289+ tests = tests . WithDegreeOfParallelism ( degreeOfParallelism . Value ) ;
290+
291+ return tests . Where ( v => Number . IsPrime ( v ) ) ;
292+ }
293+
187294 /// <summary>
188295 /// Finds the next prime number after the number given.
189296 /// </summary>
@@ -194,7 +301,6 @@ public static ulong Next(ulong after)
194301 return Numbers ( after + 1 ) . First ( ) ;
195302 }
196303
197-
198304 /// <summary>
199305 /// Finds the next prime number after the number given.
200306 /// </summary>
@@ -236,6 +342,11 @@ public static bool IsPrime(this double value)
236342 {
237343 return Number . IsPrime ( value ) ;
238344 }
345+ public static bool IsPrime ( this BigInteger value )
346+ {
347+ return Number . IsPrime ( value ) ;
348+ }
349+
239350 public static ulong NextPrime ( this ulong value )
240351 {
241352 return Prime . Next ( value ) ;
0 commit comments