// // On an HP Z600, It takes about 38 seconds to generate // the first 150 million primes (about 4 million primes per second) // public static UInt32[] GeneratePrimes(UInt32 max, out UInt32 outPrimeCount) { if (max == UInt32.MaxValue) { throw new ArgumentOutOfRangeException("max", "max cannot be UInt32.MaxValue"); } UInt32[] primes = new UInt32[PrimeCount.UpperBound(max)]; UInt32 primeCount; UInt32 maxSquareRoot = (UInt32)Math.Sqrt(max); BetterBitArray isComposite = new BetterBitArray((max + 1) >> 1); primes[0] = 2; primes[1] = 3; primeCount = 2; UInt32 candidatePrime; UInt32 incrementAmount = 0; for (candidatePrime = 5; candidatePrime <= maxSquareRoot; candidatePrime += incrementAmount) { if (!isComposite.Get(candidatePrime >> 1)) { // // Mark all multiples of this prime as composites // UInt32 candidatePrimeDoubled = 2 * candidatePrime; for (UInt32 j = candidatePrime * candidatePrime; j <= max; j += candidatePrimeDoubled) { isComposite.Assert(j >> 1); } // // Add to the primes // primes[primeCount++] = candidatePrime; } incrementAmount = (incrementAmount == 2) ? 4U : 2U; } // Add the rest of the primes for (; candidatePrime <= max; candidatePrime += incrementAmount) { if (!isComposite.Get(candidatePrime >> 1)) { primes[primeCount++] = candidatePrime; } incrementAmount = (incrementAmount == 2) ? 4U : 2U; } outPrimeCount = primeCount; return(primes); }
public static UInt32[] GeneratePrimes(UInt32 max, out UInt32 outPrimeCount) { if (max < 5) { throw new ArgumentOutOfRangeException("max", "max can't be too small"); } if (max == UInt32.MaxValue) { throw new ArgumentOutOfRangeException("max", "max cannot be UInt32.MaxValue"); } UInt32[] primes = new UInt32[PrimeCount.UpperBound(max)]; UInt32 primeCount; UInt32 maxSquareRoot = (UInt32)Math.Sqrt(max); BetterBitArray isPrime = new BetterBitArray(max + 1); // put in candidate primes for (UInt32 i = 1; i <= maxSquareRoot; i++) { for (UInt32 j = 1; j <= maxSquareRoot; j++) { UInt32 n; n = 4 * i + j; //if (n > max) throw new InvalidOperationException(); if (n <= max) // Should always be true for large enough max (maybe take this out0 { UInt32 nMod12 = n % 12; if (nMod12 == 1 || nMod12 == 5) { isPrime.Flip(n); } } n = 3 * i + j; //if (n > max) throw new InvalidOperationException(); if (n <= max) // Should always be true for large enough max (maybe take this out0 { UInt32 nMod12 = n % 12; if (nMod12 == 7) { isPrime.Flip(n); } } if (i > j) { n = 3 * i - j; //if (n > max) throw new InvalidOperationException(); if (n <= max) // Should always be true for large enough max (maybe take this out0 { UInt32 nMod12 = n % 12; if (nMod12 == 11) { isPrime.Flip(n); } } } } } primes[0] = 2; primes[1] = 3; primeCount = 2; UInt32 candidatePrime; for (candidatePrime = 5; candidatePrime <= maxSquareRoot; candidatePrime += 2) { if (isPrime.Get(candidatePrime)) { // // Mark all multiples of its square as composite // // UInt32 candidatePrimeSquared = candidatePrime * candidatePrime; //UInt32 candidatePrimeSquaredThenDoubled = iSquared * 2; for (UInt32 j = candidatePrimeSquared; j <= max; j += candidatePrimeSquared) { isPrime.Deassert(j); } // // Add to the primes // primes[primeCount++] = candidatePrime; } } // Add the rest of the primes for (; candidatePrime <= max; candidatePrime += 2) { if (isPrime.Get(candidatePrime)) { primes[primeCount++] = candidatePrime; } } outPrimeCount = primeCount; return(primes); }