Skip to content

Commit 9cc5556

Browse files
Merge pull request #1 from Open-NET-Libraries/investigation
Updates to 2.0
2 parents 4d12547 + 7dae698 commit 9cc5556

11 files changed

+785
-185
lines changed

README.md

+52
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,55 @@
33
Methods and extensions for prime number detection and discovery.
44

55
[![NuGet](https://img.shields.io/nuget/v/Open.Numeric.Primes.svg)](https://www.nuget.org/packages/Open.Numeric.Primes/)
6+
7+
## Examples
8+
9+
### Importing
10+
11+
```cs
12+
using Open.Numeric.Primes;
13+
```
14+
15+
### Primality Test
16+
17+
```cs
18+
Number.IsPrime(8592868089022906369) // true
19+
```
20+
21+
### Factors
22+
23+
```cs
24+
Prime.Factors(12) // 2, 2, 3
25+
```
26+
27+
### Common Factors
28+
29+
```cs
30+
Prime.CommonFactors(84, 756, 108) // 2, 2, 3
31+
```
32+
33+
### Greatest Factor
34+
35+
```cs
36+
Prime.GreatestFactor(84, 756, 108) // 12
37+
```
38+
39+
### Prime Discovery
40+
41+
```cs
42+
// Will list the first 1000 primes.
43+
foreach(var prime in Prime.Numbers.Take(1000))
44+
{
45+
Console.Write(prime);
46+
}
47+
```
48+
49+
or
50+
51+
```cs
52+
// Will list the first 1000 primes greater than (or equal to) 10,000.
53+
foreach(var prime in Prime.Numbers.StartingAt(10000).Take(100))
54+
{
55+
Console.Write(prime);
56+
}
57+
```

source/Open.Numeric.Primes.csproj

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111

1212
Part of the "Open" set of libraries.
1313
</Description>
14-
<PackageTags>prime numbers;primes;prime factorization;prime detection;prime discovery</PackageTags>
14+
<PackageTags>prime numbers;primes;prime factorization;prime detection;prime discovery;primality;primality test;factors;common factors;greatest factor;</PackageTags>
1515
<Copyright>© electricessence (Oren F.) All rights reserved.</Copyright>
1616
<PackageProjectUrl>https://github.com/Open-NET-Libraries/Open.Numeric.Primes/</PackageProjectUrl>
1717
<RepositoryUrl>https://github.com/Open-NET-Libraries/Open.Numeric.Primes/</RepositoryUrl>
1818
<RepositoryType>git</RepositoryType>
19-
<Version>1.6.0</Version>
19+
<Version>2.0.0</Version>
2020
<PackageReleaseNotes></PackageReleaseNotes>
2121
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2222
<PublishRepositoryUrl>true</PublishRepositoryUrl>
@@ -39,6 +39,7 @@
3939
<ItemGroup>
4040
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
4141
<PackageReference Include="Open.Collections" Version="2.8.0" />
42+
<PackageReference Include="System.Collections.Immutable" Version="1.7.1" />
4243
</ItemGroup>
4344

4445
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">

source/Optimized.cs

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
using System.Linq;
1+
using System;
2+
using System.Linq;
23
using System.Numerics;
34

45
namespace Open.Numeric.Primes
56
{
67
public class Optimized : PrimalityU64Base
78
{
9+
const uint PERF_PIVOT = 805000000;
10+
811
protected override bool IsPrimeInternal(in ulong value)
9-
{
10-
return value < 805000000
11-
? Polynomial.IsPrimeInternal(in value)
12+
=> value < PERF_PIVOT
13+
? Polynomial.IsPrimeInternal(Convert.ToUInt32(value))
1214
: MillerRabin.IsPrime(in value);
13-
}
1415

1516
public readonly BigInt Big = new BigInt();
1617

@@ -19,7 +20,10 @@ public class BigInt : PrimalityBigIntBase
1920
protected override bool IsPrimeInternal(in BigInteger value)
2021
{
2122
if (value <= ulong.MaxValue)
23+
{
24+
if (value < PERF_PIVOT) Polynomial.IsPrimeInternal(Convert.ToUInt32(value));
2225
return MillerRabin.IsPrime((ulong)value);
26+
}
2327

2428
return MillerRabin.IsProbablePrime(in value) && Polynomial.IsPrime(in value, 6);
2529

source/Polynomial.cs

+64-8
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,34 @@ namespace Open.Numeric.Primes
44
{
55
public static class Polynomial
66
{
7-
const ulong MAX_ULONG_DIVISOR = 25043747693UL;
7+
const uint MAX_UINT_DIVISOR = 65536U;
88

9-
internal static bool IsPrimeInternal(in ulong value)
9+
internal static bool IsPrimeInternal(uint value)
1010
{
11-
ulong divisor = 6;
11+
uint divisor = 6;
12+
while (divisor * divisor - 2 * divisor + 1 <= value)
13+
{
14+
if (value % (divisor - 1) == 0)
15+
return false;
16+
17+
if (value % (divisor + 1) == 0)
18+
return false;
19+
20+
divisor += 6;
21+
22+
if (divisor > MAX_UINT_DIVISOR)
23+
return IsPrimeInternal(value, divisor);
24+
}
25+
return true;
26+
}
27+
28+
const ulong MAX_ULONG_DIVISOR = 4294967296UL;
29+
30+
internal static bool IsPrimeInternal(in ulong value, ulong divisor = 6)
31+
{
32+
if (divisor > MAX_ULONG_DIVISOR)
33+
return IsPrime(value, divisor);
34+
1235
while (divisor * divisor - 2 * divisor + 1 <= value)
1336
{
1437
if (value % (divisor - 1) == 0)
@@ -22,9 +45,35 @@ internal static bool IsPrimeInternal(in ulong value)
2245
if (divisor > MAX_ULONG_DIVISOR)
2346
return IsPrime(value, divisor);
2447
}
48+
2549
return true;
2650
}
2751

52+
/// Returns true if the value provided is prime.
53+
/// </summary>
54+
/// <param name="value">The value to validate.</param>
55+
/// <returns>True if the value provided is prime</returns>
56+
public static bool IsPrime(uint value)
57+
{
58+
switch (value)
59+
{
60+
// 0 and 1 are not prime numbers
61+
case 0U:
62+
case 1U:
63+
return false;
64+
case 2U:
65+
case 3U:
66+
return true;
67+
68+
default:
69+
70+
if (value % 2 == 0 || value % 3 == 0)
71+
return false;
72+
73+
return IsPrimeInternal(value);
74+
}
75+
}
76+
2877
/// <summary>
2978
/// Returns true if the value provided is prime.
3079
/// </summary>
@@ -61,7 +110,11 @@ public static bool IsBigPrime(in BigInteger value)
61110
if (value.IsZero)
62111
return false;
63112

64-
bool primeCheck(in BigInteger v)
113+
return value.Sign == -1
114+
? value != BigInteger.MinusOne && primeCheck(BigInteger.Abs(value))
115+
: !value.IsOne && primeCheck(in value);
116+
117+
static bool primeCheck(in BigInteger v)
65118
{
66119
if (v == BIG.TWO || v == BIG.THREE)
67120
return true;
@@ -75,10 +128,6 @@ bool primeCheck(in BigInteger v)
75128
return v % 3 != 0
76129
&& IsPrime(v, 6);
77130
}
78-
79-
return value.Sign == -1
80-
? value != BigInteger.MinusOne && primeCheck(BigInteger.Abs(value))
81-
: !value.IsOne && primeCheck(in value);
82131
}
83132

84133
internal static bool IsPrime(in BigInteger value, BigInteger divisor)
@@ -97,6 +146,13 @@ internal static bool IsPrime(in BigInteger value, BigInteger divisor)
97146
return true;
98147
}
99148

149+
public class U32 : PrimalityU32Base
150+
{
151+
// ReSharper disable once MemberHidesStaticFromOuterClass
152+
protected override bool IsPrimeInternal(uint value)
153+
=> Polynomial.IsPrimeInternal(value);
154+
}
155+
100156
public class U64 : PrimalityU64Base
101157
{
102158
// ReSharper disable once MemberHidesStaticFromOuterClass

0 commit comments

Comments
 (0)