The "Sieve of Eratosthenes" optimises the calculation of prime numbers up to the limit we specify by keeping track of every number and marking if it can NOT be a prime number. It does this by finding the first prime number, 2, then marking every multiple of it as not prime, i.e. 4, 6, 8, ... and then moves to the next number that isn't so marked, which must also be prime. That would be 3 so then all multiples of 3 are marked (they may already have been marked but that doesn't matter) i.e. 6, 9, 12, ... and the process is repeated, finding 5 and marking 10, 15, 20, etc.

You could keep track of the numbers in an array and this would work perfectly well but could take up a lot of space if you were looking for all prime numbers up to, say, 500,000,000 or so. All we need to record for each number is whether it is a prime or not; this is a two-state piece of information (0 or 1 respectively) that can be held in a single bit rather than a byte or word, making for at least an 8-fold saving of space, leaving aside the mechanics of how Perl stores its internal variables. The tool Perl gives us to play around with individual bits is vec.

The vectors that vec builds are just scalar strings and can comprise multiple-bit elements but for the purposes of this discussion I will only deal with single-bit vectors. Because vectors are just strings they with always be a whole number of bytes long; if I want to use just the first 5 bits I will still get a vector of 8 bits, or 1 byte, but no matter as the last 3 that I'm not interested in can be ignored. The bits are arranged in each byte with the most significant bit first, e.g. for a vector of 16 bits taking 2 bytes the layout would be:-