Path: ...!news.mixmin.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c++ Subject: Re: Sieve of Erastosthenes optimized to the max Date: Sat, 20 Jul 2024 07:41:18 -0700 Organization: A noiseless patient Spider Lines: 56 Message-ID: <861q3o5do1.fsf@linuxsc.com> References: <86r0duwqgg.fsf@linuxsc.com> <86o78mpnlf.fsf@linuxsc.com> <86ttibod7n.fsf@linuxsc.com> <86h6eaoi2r.fsf@linuxsc.com> <867celixcw.fsf@linuxsc.com> <86zfr0b9hw.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Sat, 20 Jul 2024 16:41:19 +0200 (CEST) Injection-Info: dont-email.me; posting-host="ec269dcb7a3ff6bcf4ae70bc0b859489"; logging-data="3747114"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+s59wDri+vb6r7KfTtWxVjv8eVqKdebEE=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:8cKbooshMyjfxGRiwZ4tFu47Wm4= sha1:0RPGoyuEsNSdnpEfr0ut/OAMtlw= Bytes: 3479 Vir Campestris writes: > On 02/07/2024 07:20, Tim Rentsch wrote: > >> I got the code. [...] >> > > I checked. The modulus operations (%) are easy to check for. > > There are two for each prime number. Not for each multiple of it, but > for the primes themselves. > > And there's one in the "get" function that checks to see if a number > is prime. [...] And one divide for each modulus. Both divide and mod can be simplified if we use a different representation for numbers. The idea is to separate the number into a mod 30 part and divided by 30 part. An arbitrary number N can be split into an ordered pair N/30 , N%30 stored in, let's say, an 8 byte quantity with seven bytes for N/30 and one byte for N%30. Let me call these two parts i and a for one number N, and j and b for a second number M. Then two form N*M we need to find (i*30+a) * (j*30+b) which is (i*30*j*30) + (i*30*b) + (j*30*a) + a*b Of course we want to take the product and express it in the form (product/30, product%30), which can be done by 30*i*j + i*b + j*a + (a*b)/30, (a*b)%30 The two numbers a and b are both under 30, so a*b/30 and a*b%30 can be done by lookup in a small array. 30*i*j + i*b + j*a + divide_30[a][b], modulo_30[a][b] Now all operations can be done using just multiplies and table lookups. Dividing by 30 is just taking the first component; remainder 30 is just taking the second component. One further refinement: for numbers relatively prime to 2, 3, and 5, there are only 8 possibles, so the modulo 30 component can be reduced to just three bits. That makes the tables smaller, at a cost of needing a table lookup to find and 'a' or 'b' part. Does this all make sense?