HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Sieve32, a simple 32 bit sieve returning IEnumerable<uint> using C#

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
bitsimpleuintsievesieve32returningusingienumerable

Problem

What a difference 1 bit makes! This very fast, simple sieve of Eratosthenes quickly finds 32 bit primes. It uses a memory efficient BitArray for odd numbers – but the BitArray is at the maximum allowable length of an array. While it borrows heavily from its 31 bit counterpart, Sieve31, this sieve has some interesting differences for tweaked performance. Sieve32 is one of the more uncommon uint based sieves.

Background

See link for Sieve31 which is a 31 bit sieve returning IEnumerable.

See link for Microsoft Magic Numbers for a list of some primes (you must search the page for “prime”). This link has other interesting things in it.

public static class Sieve32
{
    public static IEnumerable Primes(uint upperLimit)
    {
        if (upperLimit  ToNumber = delegate(int index)   { return (2U * (uint)index) + offset; };
        Func ToIndex  = delegate(uint number) { return (int)((number - offset) / 2U); };
        var bits = new BitArray(ToIndex(upperLimit) + 1, defaultValue: true);
        int upperSqrtIndex = ToIndex((uint)Math.Sqrt(upperLimit));
        for (int i = 0; i  i) && (j < bits.Length); j += number31)
            {
                bits[j] = false;
            }
        }
        // Output remaining primes once bit array is resolved:
        for (int i = upperSqrtIndex + 1; i < bits.Length; i++)
        {
            if (bits[i])
            {
                yield return ToNumber(i);
            }
        }
    }
}


Deliberate Coding Against Standard Practices

For Sieve31, both the index to the BitArray and the prime numbers are int. So bouncing back and forth between a number scale and bit indices is seamless. It also employed fairly standard coding practices.

For Sieve32, the prime numbers are now uint so walking over the BitArray is a little different and sometimes confusing working with a mixture of int for indices and uint for numbers. Bouncing back and forth between a number scale and the bit indi

Solution

Short because from phone...

-
use TryGetValue() instead of ContainsKey() for the dictionary.

-
use a class level random rather than a method level random.

-
why do you throw an ArgumentException for a `upperLimit

Context

StackExchange Code Review Q#92491, answer score: 3

Revisions (0)

No revisions yet.