About Docs Source
LCOV - code coverage report
Current view: top level - src/lib/nut - sieves.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 95.7 % 702 672
Test Date: 2025-10-22 01:14:28 Functions: 100.0 % 31 31

            Line data    Source code
       1              : #include <stddef.h>
       2              : #include <stdlib.h>
       3              : #include <string.h>
       4              : #include <inttypes.h>
       5              : #include <math.h>
       6              : #include <stdio.h>
       7              : #include <unistd.h>
       8              : #include <pthread.h>
       9              : 
      10              : #include <nut/debug.h>
      11              : #include <nut/modular_math.h>
      12              : #include <nut/factorization.h>
      13              : #include <nut/sieves.h>
      14              : 
      15            6 : uint64_t nut_max_prime_divs(uint64_t max){
      16              :     //2*3*5*7*11*13*17*19*23*29*31*37*41*43*47
      17            6 :     if(max < 2ull*3){//the compiler can optimize this to a binary search if it is faster
      18              :         return 1;
      19            6 :     }else if(max < 2ull*3*5){
      20              :         return 2;
      21            6 :     }else if(max < 2ull*3*5*7){
      22              :         return 3;
      23            6 :     }else if(max < 2ull*3*5*7*11){
      24              :         return 4;
      25            4 :     }else if(max < 2ull*3*5*7*11*13){
      26              :         return 5;
      27            4 :     }else if(max < 2ull*3*5*7*11*13*17){
      28              :         return 6;
      29            4 :     }else if(max < 2ull*3*5*7*11*13*17*19){
      30              :         return 7;
      31            0 :     }else if(max < 2ull*3*5*7*11*13*17*19*23){
      32              :         return 8;
      33            0 :     }else if(max < 2ull*3*5*7*11*13*17*19*23*29){
      34              :         return 9;
      35            0 :     }else if(max < 2ull*3*5*7*11*13*17*19*23*29*31){
      36              :         return 10;
      37            0 :     }else if(max < 2ull*3*5*7*11*13*17*19*23*29*31*37){
      38              :         return 11;
      39            0 :     }else if(max < 2ull*3*5*7*11*13*17*19*23*29*31*37*41){
      40              :         return 12;
      41            0 :     }else if(max < 2ull*3*5*7*11*13*17*19*23*29*31*37*41*43){
      42              :         return 13;
      43            0 :     }else if(max < 2ull*3*5*7*11*13*17*19*23*29*31*37*41*43*47){
      44            0 :         return 14;
      45              :     }
      46              :     return 15;
      47              : }
      48              : 
      49          193 : uint64_t nut_max_primes_le(uint64_t max){
      50          193 :     return 1.25506*max/log(max);
      51              : }
      52              : 
      53            1 : void *nut_sieve_factorizations(uint64_t max, uint64_t *_w){
      54            1 :     uint64_t w = nut_max_prime_divs(max);
      55            1 :     size_t pitch = nut_get_factorizations_pitch(w);
      56            1 :     void *buf = calloc(pitch, max + 1);
      57            1 :     if(!buf){
      58              :         return NULL;
      59              :     }
      60            1 :     *_w = w;
      61      1000000 :     for(uint64_t n = 2; n <= max && n; ++n){//TODO: optimize loop
      62       999999 :         nut_Factors *factors = nut_Pitcharr_get(buf, pitch, n);
      63       999999 :         if(factors->num_primes){
      64       921501 :             continue;
      65              :         }
      66       157232 :         for(uint64_t p = n, e = 1; p <= max; ++e){
      67      3705353 :             for(uint64_t m = p; m <= max;){
      68      3626619 :                 nut_Factors *factors = nut_Pitcharr_get(buf, pitch, m);
      69      3626619 :                 uint64_t i = factors->num_primes;
      70      3626619 :                 if(e == 1){
      71      2853708 :                     ++factors->num_primes;
      72              :                 }else{
      73       772911 :                     --i;
      74              :                 }
      75      3626619 :                 factors->factors[i].prime = n;
      76      3626619 :                 factors->factors[i].power = e;
      77      3626619 :                 if(__builtin_add_overflow(m, p, &m)){
      78              :                     break;
      79              :                 }
      80              :             }
      81        78734 :             if(__builtin_mul_overflow(p, n, &p)){
      82              :                 break;
      83              :             }
      84              :         }
      85              :     }
      86              :     return buf;
      87              : }
      88              : 
      89            1 : uint64_t nut_get_factorizations_pitch(uint64_t w){
      90            1 :     static const nut_Factors dummy;
      91            1 :     return offsetof(nut_Factors, factors) + w*sizeof(dummy.factors[0]);
      92              : }
      93              : 
      94            1 : void *nut_sieve_factors(uint64_t max, uint64_t *_w){
      95            1 :     uint64_t w = nut_max_prime_divs(max);
      96            1 :     size_t pitch = nut_get_factors_pitch(w);
      97            1 :     void *buf = calloc(max + 1, pitch);
      98            1 :     if(!buf){
      99              :         return NULL;
     100              :     }
     101            1 :     *_w = w;
     102      1000000 :     for(uint64_t n = 2; n <= max && n; ++n){//TODO: optimize loop
     103       999999 :         nut_u64_Pitcharr *factors = nut_Pitcharr_get(buf, pitch, n);
     104       999999 :         if(factors->len){
     105       921501 :             continue;
     106              :         }
     107      2932206 :         for(uint64_t m = n; m <= max;){
     108      2853708 :             nut_u64_Pitcharr *factors = nut_Pitcharr_get(buf, pitch, m);
     109      2853708 :             factors->elems[factors->len++] = n;
     110      2853708 :             if(__builtin_add_overflow(m, n, &m)){
     111              :                 break;
     112              :             }
     113              :         }
     114              :     }
     115              :     return buf;
     116              : }
     117              : 
     118            1 : uint8_t *nut_sieve_omega(uint64_t max){
     119            1 :     uint8_t *buf = calloc(max + 1, sizeof(uint8_t));
     120            1 :     if(!buf){
     121              :         return NULL;
     122              :     }
     123         1000 :     for(uint64_t n = 2; n <= max && n; ++n){
     124          999 :         if(buf[n]){
     125          831 :             continue;
     126              :         }
     127         2294 :         for(uint64_t m = n; m <= max;){
     128         2126 :             buf[m]++;
     129         2126 :             if(__builtin_add_overflow(m, n, &m)){
     130              :                 break;
     131              :             }
     132              :         }
     133              :     }
     134              :     return buf;
     135              : }
     136              : 
     137            4 : uint64_t *nut_sieve_largest_factors(uint64_t max){
     138            4 :     uint64_t *buf = calloc(max + 1, sizeof(uint64_t));
     139            4 :     if(!buf){
     140              :         return NULL;
     141              :     }
     142      1011219 :     for(uint64_t n = 2; n <= max && n; ++n){
     143      1011215 :         if(buf[n]){
     144       931273 :             continue;
     145              :         }
     146      2960485 :         for(uint64_t m = n; m <= max;){
     147      2880543 :             buf[m] = n;
     148      2880543 :             if(__builtin_add_overflow(m, n, &m)){
     149              :                 break;
     150              :             }
     151              :         }
     152              :     }
     153              :     return buf;
     154              : }
     155              : 
     156            1 : uint32_t *nut_sieve_smallest_factors(uint64_t max){
     157            1 :     uint32_t *buf = calloc(max + 1, sizeof(uint32_t));
     158            1 :     if(!buf){
     159              :         return NULL;
     160              :     }
     161            1 :     uint64_t rmax = nut_u64_nth_root(max, 2);
     162           31 :     for(uint64_t n = 2; n <= rmax; ++n){
     163           30 :         if(buf[n]){
     164           19 :             continue;
     165              :         }
     166         1422 :         for(uint64_t m = n*n; m <= max;){
     167         1411 :             if(buf[m] == 0 || buf[m] > n){
     168          831 :                 buf[m] = n;
     169              :             }
     170         1411 :             if(__builtin_add_overflow(m, n, &m)){
     171              :                 break;
     172              :             }
     173              :         }
     174           11 :         buf[n] = 1; // this means the first store in the above loop is dead
     175              :     }
     176          970 :     for(uint64_t n = rmax + 1; n <= max; ++n){
     177          969 :         if(!buf[n]){
     178          157 :             buf[n] = 1;
     179              :         }
     180              :     }
     181              :     return buf;
     182              : }
     183              : 
     184            2 : uint32_t *nut_sieve_smallest_factors_wheel6(uint64_t max){
     185            2 :     uint64_t r = max%6;
     186            2 :     switch(r){
     187            0 :         case 0: max -= 1; r = 5; break;
     188            2 :         case 2 ... 4: max -= (r-1); r = 1;
     189              :     }
     190            2 :     uint64_t qmax = max/6;
     191            2 :     uint64_t max_idx = 2*qmax + (r == 5);
     192            2 :     uint32_t *buf = calloc(max_idx + 1, sizeof(uint32_t));
     193            2 :     if(!buf){
     194              :         return NULL;
     195              :     }
     196            2 :     uint64_t rmax = nut_u64_nth_root(max, 2);
     197              :     // 6*qn + 1 <= rmax
     198            2 :     uint64_t idx = 0;
     199         3297 :     for(uint64_t qn = 0; qn <= (rmax - 1)/6; ++qn){
     200         3295 :         idx += 1;
     201         3295 :         uint64_t p = 6*qn + 1;
     202         3295 :         if(buf[2*qn] == 0 && qn){ // we need to skip p = 1 and composites
     203              :             // 6*qk + 1 <= max/p
     204     49524161 :             for(uint64_t qk = qn; qk <= (max/p - 1)/6; ++qk){
     205              :                 /* (6*qn + rn)*(6*qk + rk)
     206              :                 6*((6*qn + rn)*qk + qn*rk) + rn*rk
     207              :                 */
     208     49523046 :                 uint64_t idx = 2*(p*qk + qn);
     209     49523046 :                 if(buf[idx] == 0 || buf[idx] > p){
     210     22864372 :                     buf[idx] = p;
     211              :                 }
     212              :                 // 6*qk + 5 <= max/p
     213     49523046 :                 if(qk <= (max/p - 5)/6){
     214     49522309 :                     uint64_t idx = 2*(p*qk + 5*qn) + 1;
     215     49522309 :                     if(buf[idx] == 0 || buf[idx] > p){
     216     22879805 :                         buf[idx] = p;
     217              :                     }
     218              :                 }
     219              :             }
     220              :         }
     221         3295 :         idx += 1;
     222         3295 :         if(qn){
     223         3295 :         }
     224         3295 :         buf[2*qn] = 1;
     225         3295 :         if(buf[2*qn + 1]){
     226         2170 :             continue;
     227              :         }
     228         1125 :         p += 4;
     229         1125 :         if(p > rmax){
     230              :             break;
     231              :         }
     232     58683054 :         for(uint64_t qk = qn; qk <= (max/p - 1)/6; ++qk){
     233     58681929 :             if(qk > qn){
     234     58680804 :                 uint64_t idx = 2*(p*qk + qn) + 1;
     235     58680804 :                 if(buf[idx] == 0 || buf[idx] > p){
     236     31618493 :                     buf[idx] = p;
     237              :                 }
     238              :             }
     239     58681929 :             if(qk <= (max/p - 5)/6){
     240     58681196 :                 uint64_t idx = 2*(p*qk + 5*qn + 4);
     241     58681196 :                 if(buf[idx] == 0 || buf[idx] > p){
     242     31634897 :                     buf[idx] = p;
     243              :                 }
     244              :             }
     245              :         }
     246         1125 :         buf[2*qn + 1] = 1;
     247              :     }
     248    129791790 :     for(; idx <= max_idx; ++idx){
     249    129791788 :         if(!buf[idx]){
     250     20798569 :             buf[idx] = 1;
     251              :         }
     252              :     }
     253              :     return buf;
     254              : }
     255              : 
     256      1005215 : void nut_fill_factors_from_largest(nut_Factors *restrict out, uint64_t n, const uint64_t largest_factors[restrict static n + 1]){
     257      1005215 :     out->num_primes = 0;
     258      4653844 :     for(uint64_t p = largest_factors[n], k = 1; p;){
     259      3648629 :         n /= p;
     260      3648629 :         uint64_t q = largest_factors[n];
     261      3648629 :         if(p == q){
     262       779955 :             ++k;
     263              :         }else{
     264      2868674 :             nut_Factor_append(out, p, k);
     265      2868674 :             p = q;
     266      2868674 :             k = 1;
     267              :         }
     268              :     }
     269      1005215 : }
     270              : 
     271         1000 : void nut_fill_factors_from_smallest(nut_Factors *restrict out, uint64_t n, const uint32_t smallest_factors[restrict static n + 1]){
     272         1000 :     out->num_primes = 0;
     273         3877 :     for(uint64_t p = smallest_factors[n], k = 1; p;){
     274         2877 :         if(p == 1){
     275          168 :             p = n;
     276              :         }
     277         2877 :         n /= p;
     278         2877 :         uint64_t q = smallest_factors[n];
     279         2877 :         if(q == 1){
     280          831 :             q = n;
     281              :         }
     282         2877 :         if(p == q){
     283          751 :             ++k;
     284              :         }else{
     285         2126 :             nut_Factor_append(out, p, k);
     286         2126 :             p = q;
     287         2126 :             k = 1;
     288              :         }
     289              :     }
     290         1000 : }
     291              : 
     292         1000 : void nut_fill_factors_from_smallest_wheel6(nut_Factors *restrict out, uint64_t n, const uint32_t smallest_factors[restrict static n/3 + 1]){
     293         1000 :     out->num_primes = 0;
     294         1000 :     uint64_t t = __builtin_ctzll(n);
     295         1000 :     if(t){
     296          500 :         nut_Factor_append(out, 2, t);
     297          500 :         n >>= t;
     298              :     }
     299         1000 :     t = 0;
     300         1498 :     while(n%3 == 0){
     301          498 :         ++t;
     302          498 :         n /= 3;
     303              :     }
     304         1000 :     if(t){
     305          333 :         nut_Factor_append(out, 3, t);
     306              :     }
     307         1377 :     while(n != 1){
     308         1293 :         uint64_t p = smallest_factors[n/3];
     309         1293 :         if(p == 1){
     310          916 :             nut_Factor_append(out, n, 1);
     311          916 :             break;
     312              :         }
     313              :         t = 0;
     314          832 :         while(n%p == 0){
     315          455 :             n /= p;
     316          455 :             t += 1;
     317              :         }
     318          377 :         nut_Factor_append(out, p, t);
     319              :     }
     320         1000 : }
     321              : 
     322            1 : uint64_t nut_get_factors_pitch(uint64_t w){
     323            1 :     return offsetof(nut_u64_Pitcharr, elems) + w*sizeof(uint64_t);
     324              : }
     325              : 
     326              : // Works by multiplying power + 1 for all prime factors
     327            4 : uint64_t *nut_sieve_sigma_0(uint64_t max){
     328            4 :     uint64_t *buf = malloc((max + 1)*sizeof(uint64_t));
     329            4 :     if(!buf){
     330              :         return NULL;
     331              :     }
     332      1002223 :     for(uint64_t i = 1; i <= max && i; ++i){
     333      1002219 :         buf[i] = 1;
     334              :     }
     335      1002219 :     for(uint64_t n = 2; n <= max && n; ++n){//TODO: optimize loop
     336      1002215 :         if(buf[n] != 1){
     337       923334 :             continue;
     338              :         }
     339      2937250 :         for(uint64_t m = n; m <= max;){
     340      2858369 :             uint64_t a = m/n, e = 1;
     341      3632935 :             while(a%n == 0){
     342       774566 :                 a /= n;
     343       774566 :                 ++e;
     344              :             }
     345      2858369 :             buf[m] *= e + 1;
     346      2858369 :             if(__builtin_add_overflow(m, n, &m)){
     347              :                 break;
     348              :             }
     349              :         }
     350              :     }
     351              :     return buf;
     352              : }
     353              : 
     354              : // Works by multiplying (prime**(power+1)-1)/(prime-1) for all prime factors
     355            1 : uint64_t *nut_sieve_sigma_1(uint64_t max){
     356            1 :     uint64_t *buf = malloc((max + 1)*sizeof(uint64_t));
     357            1 :     if(!buf){
     358              :         return NULL;
     359              :     }
     360      1000001 :     for(uint64_t i = 1; i <= max && i; ++i){
     361      1000000 :         buf[i] = 1;
     362              :     }
     363      1000000 :     for(uint64_t n = 2; n <= max && n; ++n){//TODO: optimize loop
     364       999999 :         if(buf[n] != 1){
     365       921501 :             continue;
     366              :         }
     367      2932206 :         for(uint64_t m = n; m <= max;){
     368      2853708 :             uint64_t a = n*n;
     369      3626619 :             while(m%a == 0){
     370       772911 :                 a *= n;
     371              :             }
     372      2853708 :             buf[m] *= (a - 1)/(n - 1);
     373      2853708 :             if(__builtin_add_overflow(m, n, &m)){
     374              :                 break;
     375              :             }
     376              :         }
     377              :     }
     378              :     return buf;
     379              : }
     380              : 
     381              : // Works by multiplying (prime**((power+1)*e)-1)/(prime**e-1) for all prime factors, where power is the
     382              : // power of each prime and e is the power of divisors to sum
     383            1 : uint64_t *nut_sieve_sigma_e(uint64_t max, uint64_t e){
     384            1 :     uint64_t *buf = malloc((max + 1)*sizeof(uint64_t));
     385            1 :     if(!buf){
     386              :         return NULL;
     387              :     }
     388      1000001 :     for(uint64_t i = 1; i <= max && i; ++i){
     389      1000000 :         buf[i] = 1;
     390              :     }
     391      1000000 :     for(uint64_t n = 2; n <= max && n; ++n){//TODO: optimize loop
     392       999999 :         if(buf[n] != 1){
     393       921501 :             continue;
     394              :         }
     395      2932206 :         for(uint64_t m = n; m <= max;){
     396      2853708 :             uint64_t a = n*n;
     397      3626619 :             while(m%a == 0){
     398       772911 :                 a *= n;
     399              :             }
     400      2853708 :             buf[m] *= (nut_u64_pow(a, e) - 1)/(nut_u64_pow(n, e) - 1);
     401      2853708 :             if(__builtin_add_overflow(m, n, &m)){
     402              :                 break;
     403              :             }
     404              :         }
     405              :     }
     406              :     return buf;
     407              : }
     408              : 
     409           37 : bool nut_u64_make_factorial_tbl(uint64_t k, uint64_t modulus, uint64_t bits, uint64_t max_denom, uint64_t factorials[static bits + k], uint64_t inv_factorials[static max_denom + 1]){
     410           37 :     factorials[0] = 1;
     411         3947 :     for(uint64_t i = 1; i < bits + k; ++i){
     412         3910 :         factorials[i] = factorials[i - 1]*i%modulus;
     413              :     }
     414           37 :     memcpy(inv_factorials, factorials, 2*sizeof(uint64_t));
     415         3620 :     for(uint64_t i = 2; i <= max_denom; ++i){
     416         3583 :         int64_t inv;
     417         3583 :         if(nut_i64_egcd(factorials[i], modulus, &inv, NULL) != 1){
     418            0 :             return false;
     419         3583 :         }else if(inv < 0){
     420         1827 :             inv_factorials[i] = inv + (int64_t)modulus;
     421              :         }else{
     422         1756 :             inv_factorials[i] = inv;
     423              :         }
     424              :     }
     425              :     return true;
     426              : }
     427              : 
     428           19 : static uint64_t *sieve_dk_mod(uint64_t max, uint64_t k, uint64_t modulus){
     429           19 :     uint64_t *buf = malloc((max + 1)*sizeof(uint64_t));
     430           38 :     uint8_t *is_c_buf [[gnu::cleanup(cleanup_free)]] = calloc(max/8 + 1, sizeof(uint8_t));
     431           19 :     uint64_t bits = 64 - __builtin_clzll(max);
     432           19 :     uint64_t max_denom = bits > k - 1 ? bits : k - 1;
     433           38 :     uint64_t *factorials [[gnu::cleanup(cleanup_free)]] = malloc((bits + k)*sizeof(uint64_t));
     434           38 :     uint64_t *inv_factorials [[gnu::cleanup(cleanup_free)]] = malloc((max_denom + 1)*sizeof(uint64_t));
     435           19 :     if(!buf || !is_c_buf || !factorials || !inv_factorials || modulus > INT64_MAX){
     436              :         return NULL;
     437              :     }
     438      1003961 :     for(uint64_t i = 1; i <= max && i; ++i){
     439      1003942 :         buf[i] = 1;
     440              :     }
     441           19 :     if(!nut_u64_make_factorial_tbl(k, modulus, bits, max_denom, factorials, inv_factorials)){
     442              :         return NULL;
     443              :     }
     444      1003942 :     for(uint64_t n = 2; n <= max && n; ++n){//TODO: optimize loop
     445      1003923 :         if(nut_Bitarray_get(is_c_buf, n)){
     446       924579 :             continue;
     447              :         }
     448      2940414 :         for(uint64_t m = n; m <= max;){
     449      2861070 :             nut_Bitarray_set(is_c_buf, m, 1);
     450      2861070 :             uint64_t m1 = m, a = 0;
     451      6497805 :             while(m1%n == 0){
     452      3636735 :                 m1 /= n;
     453      3636735 :                 ++a;
     454              :             }
     455      2861070 :             uint64_t term = buf[m]*factorials[a + k - 1]%modulus;
     456      2861070 :             term = term*inv_factorials[k - 1]%modulus;
     457      2861070 :             buf[m] = term*inv_factorials[a]%modulus;
     458      2861070 :             if(__builtin_add_overflow(m, n, &m)){
     459              :                 break;
     460              :             }
     461              :         }
     462              :     }
     463              :     return buf;
     464              : }
     465              : 
     466            6 : static uint64_t *sieve_dk_u64(uint64_t max, uint64_t k){
     467            6 :     uint64_t *buf = malloc((max + 1)*sizeof(uint64_t));
     468           12 :     uint8_t *is_c_buf [[gnu::cleanup(cleanup_free)]] = calloc(max/8 + 1, sizeof(uint8_t));
     469            6 :     if(!buf || !is_c_buf){
     470              :         return NULL;
     471              :     }
     472      1005006 :     for(uint64_t i = 1; i <= max && i; ++i){
     473      1005000 :         buf[i] = 1;
     474              :     }
     475      1005000 :     for(uint64_t n = 2; n <= max && n; ++n){//TODO: optimize loop
     476      1004994 :         if(nut_Bitarray_get(is_c_buf, n)){
     477       925656 :             continue;
     478              :         }
     479      2943676 :         for(uint64_t m = n; m <= max;){
     480      2864338 :             nut_Bitarray_set(is_c_buf, m, 1);
     481      2864338 :             uint64_t m1 = m, a = 0;
     482      6505342 :             while(m1%n == 0){
     483      3641004 :                 m1 /= n;
     484      3641004 :                 ++a;
     485              :             }
     486      2864338 :             buf[m] *= nut_u64_binom(a + k - 1, k - 1);
     487      2864338 :             if(__builtin_add_overflow(m, n, &m)){
     488              :                 break;
     489              :             }
     490              :         }
     491              :     }
     492              :     return buf;
     493              : }
     494              : 
     495           25 : uint64_t *nut_sieve_dk(uint64_t max, uint64_t k, uint64_t modulus){
     496           25 :     return modulus ? sieve_dk_mod(max, k, modulus) : sieve_dk_u64(max, k);
     497              : }
     498              : 
     499            2 : uint64_t *nut_sieve_phi(uint64_t max){
     500            2 :     uint64_t *buf = malloc((max + 1)*sizeof(uint64_t));
     501            2 :     if(!buf){
     502              :         return NULL;
     503              :     }
     504      1001002 :     for(uint64_t i = 1; i <= max && i; ++i){
     505      1001000 :         buf[i] = 1;
     506              :     }
     507      1001000 :     for(uint64_t n = 2; n <= max && n; ++n){//TODO: optimize loop
     508      1000998 :         if(buf[n] != 1){
     509       922332 :             continue;
     510              :         }
     511      2934500 :         for(uint64_t m = n; m <= max;){
     512      2855834 :             uint64_t a = n*n;
     513      3629496 :             while(m%a == 0){
     514       773662 :                 a *= n;
     515              :             }
     516      2855834 :             buf[m] *= a/n - a/n/n;
     517      2855834 :             if(__builtin_add_overflow(m, n, &m)){
     518              :                 break;
     519              :             }
     520              :         }
     521              :     }
     522              :     return buf;
     523              : }
     524              : 
     525            2 : uint64_t *nut_sieve_carmichael(uint64_t max){
     526            2 :     uint64_t *buf = malloc((max + 1)*sizeof(uint64_t));
     527            2 :     if(!buf){
     528              :         return NULL;
     529              :     }
     530      1010002 :     for(uint64_t i = 1; i <= max && i; ++i){
     531      1010000 :         buf[i] = 1;
     532              :     }
     533              :     uint64_t t = 4, b = 1;
     534           34 :     while((t >> 1) <= max){
     535       505032 :         for(uint64_t m = t >> 1; m <= max; m += t){
     536       505000 :             buf[m] = b;
     537              :         }
     538           32 :         t <<= 1;
     539           32 :         if(t != 16){
     540           30 :             b <<= 1;
     541              :         }
     542              :     }
     543       505000 :     for(uint64_t n = 1; !__builtin_add_overflow(n, 2, &n) && n <= max;){//TODO: optimize loop
     544       504998 :         if(buf[n] != 1){
     545       425273 :             continue;
     546              :         }
     547      2452733 :         for(uint64_t k = 1, m = n; k <= max/n; ++k, m += n){
     548      2373008 :             uint64_t a = n - 1;
     549      2648616 :             for(uint64_t j = k; j%n == 0; j /= n){
     550       275608 :                 a *= n;
     551              :             }
     552      2373008 :             buf[m] = nut_i64_lcm(buf[m], a);
     553              :         }
     554              :     }
     555              :     return buf;
     556              : }
     557              : 
     558            3 : uint8_t *nut_sieve_mobius(uint64_t max){
     559            3 :     uint64_t buf_len = max/4 + 1;
     560            3 :     uint8_t *buf = malloc(buf_len*sizeof(uint64_t));
     561            3 :     if(!buf){
     562              :         return NULL;
     563              :     }
     564              :     // Initialize buf to be 0 for 0, 1 for 1, and 2 for every other n <= max.
     565              :     // 2 is not a valid output value, so we use it here to mark a number as prime
     566              :     // until they are marked off by being the factor of some other number.
     567            3 :     buf[0] = 0xA4u;
     568            3 :     memset(buf + 1, 0xAA, (buf_len - 1)*sizeof(uint8_t));
     569      2160428 :     for(uint64_t n = 2; n <= max && n; ++n){
     570      2160425 :         if(((buf[n/4] >> (n%4*2)) & 3) != 2){
     571      1991858 :             continue;
     572              :         }
     573       168567 :         buf[n/4] ^= 1ull << (n%4*2);
     574       168567 :         uint64_t m;
     575       168567 :         if(__builtin_mul_overflow(n, 2, &m)){
     576            0 :             continue;
     577              :         }
     578              :         // First we visit all multiples of n and flip their mobius value
     579              :         // We need to send 2 to 3, 1 to 3, 3 to 1, and 0 to 0.
     580              :         // We can do this by using an xor mask so we only have to
     581              :         // get x from the array and then xor the array with this mask.
     582      6178061 :         while(m <= max){
     583      6009494 :             uint8_t x = (buf[m/4] >> (m%4*2)) & 3;
     584      6009494 :             x = (0x98u >> (x*2)) & 3;// this constant acts as a packed lookup table for the xor mask for x
     585      6009494 :             buf[m/4] ^= x << (m%4*2);
     586      6009494 :             if(__builtin_add_overflow(m, n, &m)){
     587              :                 break;
     588              :             }
     589              :         }
     590       168567 :         uint64_t n2;
     591              :         // Here we visit all multiples of n**2 and set their mobius value to 0,
     592              :         // since they are not square free.
     593       168567 :         if(!__builtin_mul_overflow(n, n, &n2)){
     594      1145197 :             for(uint64_t m = n2; m <= max;){
     595       976630 :                 buf[m/4] &= ~(3u << (m%4*2));
     596       976630 :                 if(__builtin_add_overflow(m, n2, &m)){
     597              :                     break;
     598              :                 }
     599              :             }
     600              :         }
     601              :     }
     602              :     return buf;
     603              : }
     604              : 
     605            1 : int64_t *nut_compute_mertens_range(uint64_t max, const uint8_t mobius[static max/4 + 1]){
     606            1 :     int64_t *buf = malloc((max + 1)*sizeof(int64_t));
     607            1 :     if(!buf){
     608              :         return NULL;
     609              :     }
     610            1 :     buf[0] = 0;
     611      1000001 :     for(uint64_t n = 1; n <= max; ++n){
     612      1000000 :         int64_t v = nut_Bitfield2_arr_get(mobius, n);
     613      1000000 :         if(v == 3){
     614       303857 :             v = -1;
     615              :         }
     616      1000000 :         buf[n] = buf[n - 1] + v;
     617              :     }
     618              :     return buf;
     619              : }
     620              : 
     621          518 : static void mark_is_composite(uint8_t *is_composite, uint64_t q, uint64_t r, uint64_t q_ub){
     622              :     /* We need to find the first multiple of the prime 30*q + r which could possibly be prime and is at least the prime squared.
     623              :      * Since the prime squared is still coprime to the wheel size, we start at the prime squared.
     624              :      * (30*q + r)**2 = 30*30*q**2 + 30*2*q*r + r**2 = 30*(30*q**2 + 2*q*r) + r**2
     625              :      */
     626          518 :     uint64_t mq;
     627          518 :     switch(r){
     628           55 :         case 1:
     629           55 :             mq = q*(30*q + 2) + 0;// mr = 1
     630         8437 :             for(; mq + 28*q + 0 < q_ub; mq += 30*q + 1){
     631         8382 :                 is_composite[mq] |= 0x1;// mr = 1
     632         8382 :                 is_composite[mq + 6*q + 0] |= 0x2;// mr = 7
     633         8382 :                 is_composite[mq + 10*q + 0] |= 0x4;// mr = 11
     634         8382 :                 is_composite[mq + 12*q + 0] |= 0x8;// mr = 13
     635         8382 :                 is_composite[mq + 16*q + 0] |= 0x10;// mr = 17
     636         8382 :                 is_composite[mq + 18*q + 0] |= 0x20;// mr = 19
     637         8382 :                 is_composite[mq + 22*q + 0] |= 0x40;// mr = 23
     638         8382 :                 is_composite[mq + 28*q + 0] |= 0x80;// mr = 29
     639              :             }
     640           55 :             if(mq >= q_ub){break;}
     641           49 :             is_composite[mq] |= 0x1;// mr = 1
     642           49 :             if((mq += 6*q + 0) >= q_ub){break;}
     643           39 :             is_composite[mq] |= 0x2;// mr = 7
     644           39 :             if((mq += 4*q + 0) >= q_ub){break;}
     645           30 :             is_composite[mq] |= 0x4;// mr = 11
     646           30 :             if((mq += 2*q + 0) >= q_ub){break;}
     647           21 :             is_composite[mq] |= 0x8;// mr = 13
     648           21 :             if((mq += 4*q + 0) >= q_ub){break;}
     649           15 :             is_composite[mq] |= 0x10;// mr = 17
     650           15 :             if((mq += 2*q + 0) >= q_ub){break;}
     651           12 :             is_composite[mq] |= 0x20;// mr = 19
     652           12 :             if((mq += 4*q + 0) >= q_ub){break;}
     653            3 :             is_composite[mq] |= 0x40;// mr = 23
     654            3 :             mq += 6*q + 0; break; // If we get here, we have mq >= q_ub by the fact that we made it out of the for loop
     655           74 :         case 7:
     656           74 :             mq = q*(30*q + 14) + 1;// mr = 19
     657        23187 :             for(; mq + 24*q + 6 < q_ub; mq += 30*q + 7){
     658        23113 :                 is_composite[mq] |= 0x20;// mr = 19
     659        23113 :                 is_composite[mq + 4*q + 1] |= 0x10;// mr = 17
     660        23113 :                 is_composite[mq + 6*q + 2] |= 0x1;// mr = 1
     661        23113 :                 is_composite[mq + 10*q + 2] |= 0x80;// mr = 29
     662        23113 :                 is_composite[mq + 12*q + 3] |= 0x8;// mr = 13
     663        23113 :                 is_composite[mq + 16*q + 4] |= 0x4;// mr = 11
     664        23113 :                 is_composite[mq + 22*q + 5] |= 0x40;// mr = 23
     665        23113 :                 is_composite[mq + 24*q + 6] |= 0x2;// mr = 7
     666              :             }
     667           74 :             if(mq >= q_ub){break;}
     668           70 :             is_composite[mq] |= 0x20;// mr = 19
     669           70 :             if((mq += 4*q + 1) >= q_ub){break;}
     670           61 :             is_composite[mq] |= 0x10;// mr = 17
     671           61 :             if((mq += 2*q + 1) >= q_ub){break;}
     672           61 :             is_composite[mq] |= 0x1;// mr = 1
     673           61 :             if((mq += 4*q + 0) >= q_ub){break;}
     674           46 :             is_composite[mq] |= 0x80;// mr = 29
     675           46 :             if((mq += 2*q + 1) >= q_ub){break;}
     676           40 :             is_composite[mq] |= 0x8;// mr = 13
     677           40 :             if((mq += 4*q + 1) >= q_ub){break;}
     678           34 :             is_composite[mq] |= 0x4;// mr = 11
     679           34 :             if((mq += 6*q + 1) >= q_ub){break;}
     680            6 :             is_composite[mq] |= 0x40;// mr = 23
     681            6 :             mq += 2*q + 1; break; // If we get here, we have mq >= q_ub by the fact that we made it out of the for loop
     682           68 :         case 11:
     683           68 :             mq = q*(30*q + 22) + 4;// mr = 1
     684        17386 :             for(; mq + 26*q + 9 < q_ub; mq += 30*q + 11){
     685        17318 :                 is_composite[mq] |= 0x1;// mr = 1
     686        17318 :                 is_composite[mq + 2*q + 0] |= 0x40;// mr = 23
     687        17318 :                 is_composite[mq + 6*q + 2] |= 0x2;// mr = 7
     688        17318 :                 is_composite[mq + 8*q + 2] |= 0x80;// mr = 29
     689        17318 :                 is_composite[mq + 12*q + 4] |= 0x8;// mr = 13
     690        17318 :                 is_composite[mq + 18*q + 6] |= 0x20;// mr = 19
     691        17318 :                 is_composite[mq + 20*q + 7] |= 0x4;// mr = 11
     692        17318 :                 is_composite[mq + 26*q + 9] |= 0x10;// mr = 17
     693              :             }
     694           68 :             if(mq >= q_ub){break;}
     695           55 :             is_composite[mq] |= 0x1;// mr = 1
     696           55 :             if((mq += 2*q + 0) >= q_ub){break;}
     697           52 :             is_composite[mq] |= 0x40;// mr = 23
     698           52 :             if((mq += 4*q + 2) >= q_ub){break;}
     699           40 :             is_composite[mq] |= 0x2;// mr = 7
     700           40 :             if((mq += 2*q + 0) >= q_ub){break;}
     701           31 :             is_composite[mq] |= 0x80;// mr = 29
     702           31 :             if((mq += 4*q + 2) >= q_ub){break;}
     703           31 :             is_composite[mq] |= 0x8;// mr = 13
     704           31 :             if((mq += 6*q + 2) >= q_ub){break;}
     705           19 :             is_composite[mq] |= 0x20;// mr = 19
     706           19 :             if((mq += 2*q + 1) >= q_ub){break;}
     707           10 :             is_composite[mq] |= 0x4;// mr = 11
     708           10 :             mq += 6*q + 2; break; // If we get here, we have mq >= q_ub by the fact that we made it out of the for loop
     709           62 :         case 13:
     710           62 :             mq = q*(30*q + 26) + 5;// mr = 19
     711        15679 :             for(; mq + 28*q + 12 < q_ub; mq += 30*q + 13){
     712        15617 :                 is_composite[mq] |= 0x20;// mr = 19
     713        15617 :                 is_composite[mq + 4*q + 2] |= 0x4;// mr = 11
     714        15617 :                 is_composite[mq + 6*q + 3] |= 0x2;// mr = 7
     715        15617 :                 is_composite[mq + 10*q + 4] |= 0x80;// mr = 29
     716        15617 :                 is_composite[mq + 16*q + 7] |= 0x10;// mr = 17
     717        15617 :                 is_composite[mq + 18*q + 8] |= 0x8;// mr = 13
     718        15617 :                 is_composite[mq + 24*q + 11] |= 0x1;// mr = 1
     719        15617 :                 is_composite[mq + 28*q + 12] |= 0x40;// mr = 23
     720              :             }
     721           62 :             if(mq >= q_ub){break;}
     722           55 :             is_composite[mq] |= 0x20;// mr = 19
     723           55 :             if((mq += 4*q + 2) >= q_ub){break;}
     724           37 :             is_composite[mq] |= 0x4;// mr = 11
     725           37 :             if((mq += 2*q + 1) >= q_ub){break;}
     726           30 :             is_composite[mq] |= 0x2;// mr = 7
     727           30 :             if((mq += 4*q + 1) >= q_ub){break;}
     728           21 :             is_composite[mq] |= 0x80;// mr = 29
     729           21 :             if((mq += 6*q + 3) >= q_ub){break;}
     730           15 :             is_composite[mq] |= 0x10;// mr = 17
     731           15 :             if((mq += 2*q + 1) >= q_ub){break;}
     732            9 :             is_composite[mq] |= 0x8;// mr = 13
     733            9 :             if((mq += 6*q + 3) >= q_ub){break;}
     734            0 :             is_composite[mq] |= 0x1;// mr = 1
     735            0 :             mq += 4*q + 1; break; // If we get here, we have mq >= q_ub by the fact that we made it out of the for loop
     736           68 :         case 17:
     737           68 :             mq = q*(30*q + 34) + 9;// mr = 19
     738        12903 :             for(; mq + 26*q + 15 < q_ub; mq += 30*q + 17){
     739        12835 :                 is_composite[mq] |= 0x20;// mr = 19
     740        12835 :                 is_composite[mq + 2*q + 1] |= 0x40;// mr = 23
     741        12835 :                 is_composite[mq + 6*q + 4] |= 0x1;// mr = 1
     742        12835 :                 is_composite[mq + 12*q + 7] |= 0x8;// mr = 13
     743        12835 :                 is_composite[mq + 14*q + 8] |= 0x10;// mr = 17
     744        12835 :                 is_composite[mq + 20*q + 11] |= 0x80;// mr = 29
     745        12835 :                 is_composite[mq + 24*q + 14] |= 0x2;// mr = 7
     746        12835 :                 is_composite[mq + 26*q + 15] |= 0x4;// mr = 11
     747              :             }
     748           68 :             if(mq >= q_ub){break;}
     749           61 :             is_composite[mq] |= 0x20;// mr = 19
     750           61 :             if((mq += 2*q + 1) >= q_ub){break;}
     751           55 :             is_composite[mq] |= 0x40;// mr = 23
     752           55 :             if((mq += 4*q + 3) >= q_ub){break;}
     753           52 :             is_composite[mq] |= 0x1;// mr = 1
     754           52 :             if((mq += 6*q + 3) >= q_ub){break;}
     755           34 :             is_composite[mq] |= 0x8;// mr = 13
     756           34 :             if((mq += 2*q + 1) >= q_ub){break;}
     757           30 :             is_composite[mq] |= 0x10;// mr = 17
     758           30 :             if((mq += 6*q + 3) >= q_ub){break;}
     759           15 :             is_composite[mq] |= 0x80;// mr = 29
     760           15 :             if((mq += 4*q + 3) >= q_ub){break;}
     761            3 :             is_composite[mq] |= 0x2;// mr = 7
     762            3 :             mq += 2*q + 1; break; // If we get here, we have mq >= q_ub by the fact that we made it out of the for loop
     763           58 :         case 19:
     764           58 :             mq = q*(30*q + 38) + 12;// mr = 1
     765        10445 :             for(; mq + 28*q + 17 < q_ub; mq += 30*q + 19){
     766        10387 :                 is_composite[mq] |= 0x1;// mr = 1
     767        10387 :                 is_composite[mq + 4*q + 2] |= 0x10;// mr = 17
     768        10387 :                 is_composite[mq + 10*q + 6] |= 0x4;// mr = 11
     769        10387 :                 is_composite[mq + 12*q + 7] |= 0x20;// mr = 19
     770        10387 :                 is_composite[mq + 18*q + 11] |= 0x8;// mr = 13
     771        10387 :                 is_composite[mq + 22*q + 13] |= 0x80;// mr = 29
     772        10387 :                 is_composite[mq + 24*q + 15] |= 0x2;// mr = 7
     773        10387 :                 is_composite[mq + 28*q + 17] |= 0x40;// mr = 23
     774              :             }
     775           58 :             if(mq >= q_ub){break;}
     776           55 :             is_composite[mq] |= 0x1;// mr = 1
     777           55 :             if((mq += 4*q + 2) >= q_ub){break;}
     778           55 :             is_composite[mq] |= 0x10;// mr = 17
     779           55 :             if((mq += 6*q + 4) >= q_ub){break;}
     780           30 :             is_composite[mq] |= 0x4;// mr = 11
     781           30 :             if((mq += 2*q + 1) >= q_ub){break;}
     782           27 :             is_composite[mq] |= 0x20;// mr = 19
     783           27 :             if((mq += 6*q + 4) >= q_ub){break;}
     784           21 :             is_composite[mq] |= 0x8;// mr = 13
     785           21 :             if((mq += 4*q + 2) >= q_ub){break;}
     786           15 :             is_composite[mq] |= 0x80;// mr = 29
     787           15 :             if((mq += 2*q + 2) >= q_ub){break;}
     788           12 :             is_composite[mq] |= 0x2;// mr = 7
     789           12 :             mq += 4*q + 2; break; // If we get here, we have mq >= q_ub by the fact that we made it out of the for loop
     790           68 :         case 23:
     791           68 :             mq = q*(30*q + 46) + 17;// mr = 19
     792        11330 :             for(; mq + 26*q + 20 < q_ub; mq += 30*q + 23){
     793        11262 :                 is_composite[mq] |= 0x20;// mr = 19
     794        11262 :                 is_composite[mq + 6*q + 5] |= 0x2;// mr = 7
     795        11262 :                 is_composite[mq + 8*q + 6] |= 0x40;// mr = 23
     796        11262 :                 is_composite[mq + 14*q + 11] |= 0x4;// mr = 11
     797        11262 :                 is_composite[mq + 18*q + 14] |= 0x8;// mr = 13
     798        11262 :                 is_composite[mq + 20*q + 15] |= 0x80;// mr = 29
     799        11262 :                 is_composite[mq + 24*q + 19] |= 0x1;// mr = 1
     800        11262 :                 is_composite[mq + 26*q + 20] |= 0x10;// mr = 17
     801              :             }
     802           68 :             if(mq >= q_ub){break;}
     803           58 :             is_composite[mq] |= 0x20;// mr = 19
     804           58 :             if((mq += 6*q + 5) >= q_ub){break;}
     805           43 :             is_composite[mq] |= 0x2;// mr = 7
     806           43 :             if((mq += 2*q + 1) >= q_ub){break;}
     807           37 :             is_composite[mq] |= 0x40;// mr = 23
     808           37 :             if((mq += 6*q + 5) >= q_ub){break;}
     809           19 :             is_composite[mq] |= 0x4;// mr = 11
     810           19 :             if((mq += 4*q + 3) >= q_ub){break;}
     811           10 :             is_composite[mq] |= 0x8;// mr = 13
     812           10 :             if((mq += 2*q + 1) >= q_ub){break;}
     813            7 :             is_composite[mq] |= 0x80;// mr = 29
     814            7 :             if((mq += 4*q + 4) >= q_ub){break;}
     815            6 :             is_composite[mq] |= 0x1;// mr = 1
     816            6 :             mq += 2*q + 1; break; // If we get here, we have mq >= q_ub by the fact that we made it out of the for loop
     817           65 :         case 29:
     818           65 :             mq = q*(30*q + 58) + 28;// mr = 1
     819         9839 :             for(; mq + 24*q + 23 < q_ub; mq += 30*q + 29){
     820         9774 :                 is_composite[mq] |= 0x1;// mr = 1
     821         9774 :                 is_composite[mq + 2*q + 1] |= 0x80;// mr = 29
     822         9774 :                 is_composite[mq + 8*q + 7] |= 0x40;// mr = 23
     823         9774 :                 is_composite[mq + 12*q + 11] |= 0x20;// mr = 19
     824         9774 :                 is_composite[mq + 14*q + 13] |= 0x10;// mr = 17
     825         9774 :                 is_composite[mq + 18*q + 17] |= 0x8;// mr = 13
     826         9774 :                 is_composite[mq + 20*q + 19] |= 0x4;// mr = 11
     827         9774 :                 is_composite[mq + 24*q + 23] |= 0x2;// mr = 7
     828              :             }
     829           65 :             if(mq >= q_ub){break;}
     830           52 :             is_composite[mq] |= 0x1;// mr = 1
     831           52 :             if((mq += 2*q + 1) >= q_ub){break;}
     832           49 :             is_composite[mq] |= 0x80;// mr = 29
     833           49 :             if((mq += 6*q + 6) >= q_ub){break;}
     834           42 :             is_composite[mq] |= 0x40;// mr = 23
     835           42 :             if((mq += 4*q + 4) >= q_ub){break;}
     836           36 :             is_composite[mq] |= 0x20;// mr = 19
     837           36 :             if((mq += 2*q + 2) >= q_ub){break;}
     838           36 :             is_composite[mq] |= 0x10;// mr = 17
     839           36 :             if((mq += 4*q + 4) >= q_ub){break;}
     840           21 :             is_composite[mq] |= 0x8;// mr = 13
     841           21 :             if((mq += 2*q + 2) >= q_ub){break;}
     842           12 :             is_composite[mq] |= 0x4;// mr = 11
     843           12 :             mq += 4*q + 4; break; // If we get here, we have mq >= q_ub by the fact that we made it out of the for loop
     844            0 :         default:
     845            0 :             __builtin_unreachable();
     846              :     }
     847          518 : }
     848              : 
     849            4 : uint8_t *nut_sieve_is_composite(uint64_t max){
     850            4 :     uint64_t is_composite_len = max/30 + 1;
     851            4 :     uint8_t *is_composite = calloc(is_composite_len, sizeof(uint64_t));
     852            4 :     if(!is_composite){
     853              :         return NULL;
     854              :     }
     855            4 :     uint64_t q_ub = is_composite_len;
     856            4 :     uint64_t p_max = nut_u64_nth_root(max, 2);
     857            4 :     uint64_t q_max = (p_max - 1)/30;
     858            4 :     uint64_t q = 0, r = 7;
     859          108 :     while(q <= q_max){
     860          104 :         uint8_t flags = is_composite[q];
     861          104 :         switch(r){
     862          100 :             case 1:
     863          100 :                 if(!(flags & 0x1)){mark_is_composite(is_composite, q, r, q_ub);}
     864          104 :                 r = 7; [[fallthrough]];
     865          104 :             case 7:
     866          104 :                 if(!(flags & 0x2)){mark_is_composite(is_composite, q, r, q_ub);}
     867          104 :                 r = 11; [[fallthrough]];
     868          104 :             case 11:
     869          104 :                 if(!(flags & 0x4)){mark_is_composite(is_composite, q, r, q_ub);}
     870          104 :                 r = 13; [[fallthrough]];
     871          104 :             case 13:
     872          104 :                 if(!(flags & 0x8)){mark_is_composite(is_composite, q, r, q_ub);}
     873          104 :                 r = 17; [[fallthrough]];
     874          104 :             case 17:
     875          104 :                 if(!(flags & 0x10)){mark_is_composite(is_composite, q, r, q_ub);}
     876          104 :                 r = 19; [[fallthrough]];
     877          104 :             case 19:
     878          104 :                 if(!(flags & 0x20)){mark_is_composite(is_composite, q, r, q_ub);}
     879          104 :                 r = 23; [[fallthrough]];
     880          104 :             case 23:
     881          104 :                 if(!(flags & 0x40)){mark_is_composite(is_composite, q, r, q_ub);}
     882          104 :                 r = 29; [[fallthrough]];
     883          104 :             case 29:
     884          104 :                 if(!(flags & 0x80)){mark_is_composite(is_composite, q, r, q_ub);}
     885              :                 r = 1;
     886              :                 ++q;
     887              :                 break;
     888            0 :             default:
     889            0 :                 __builtin_unreachable();
     890              :         }
     891              :     }
     892              :     return is_composite;
     893              : }
     894              : 
     895      1000000 : bool nut_is_composite(uint64_t n, const uint8_t buf[static n/30 + 1]){
     896      1000000 :     if(n < 6){
     897            5 :         return n != 2 && n != 3 && n != 5;
     898              :     }
     899       999995 :     uint64_t r = n%30;
     900       999995 :     uint64_t q = n/30;
     901       999995 :     switch(r){
     902        33333 :         case 1: return buf[q] & 0x1;
     903        33334 :         case 7: return buf[q] & 0x2;
     904        33333 :         case 11: return buf[q] & 0x4;
     905        33333 :         case 13: return buf[q] & 0x8;
     906        33333 :         case 17: return buf[q] & 0x10;
     907        33333 :         case 19: return buf[q] & 0x20;
     908        33333 :         case 23: return buf[q] & 0x40;
     909        33333 :         case 29: return buf[q] & 0x80;
     910              :         default: return true;
     911              :     }
     912              : }
     913              : 
     914            2 : uint64_t *nut_compute_pi_range(uint64_t max, const uint8_t buf[static max/30 + 1]){
     915              :     /* buf[i] tells us the primality of 30*i + 1, 30*i + 7, 30*i + 11, ..., 30*i + 29.
     916              :      * Thus, we want res[i] to tell us the number of prime numbers from 1 up to 30*(i + 1)
     917              :      * and so in general res[i] = popcount(buf[i]) + res[i - 1].
     918              :      * However, res[0], the number of primes up to 30, is instead 10.
     919              :      * Finally, since max is inclusive, we must have res[max/30 - 1].
     920              :      * The -1 is because since res[0] is the number of primes up to 30, for arguments i < 30 we have to
     921              :      * special case their lookup, so the domain essentially starts at 30.
     922              :      */
     923            2 :     uint64_t res_len = max/30;
     924            2 :     uint64_t *res = calloc(res_len, sizeof(uint64_t));
     925            2 :     if(!res){
     926              :         return NULL;
     927              :     }
     928            2 :     res[0] = 10;
     929        66666 :     for(uint64_t i = 1, acc = 10; i < res_len; ++i){
     930        66664 :         res[i] = acc += __builtin_popcount(0xFF&~buf[i]);
     931              :     }
     932              :     return res;
     933              : }
     934              : 
     935      1002000 : uint64_t nut_compute_pi_from_tables(uint64_t n, const uint64_t pi_table[restrict static n/30], const uint8_t buf[restrict static n/30 + 1]){
     936      1002000 :     if(n < 30){
     937              :         uint64_t res;
     938          400 :         for(res = 0; nut_small_primes[res] <= n; ++res);
     939              :         return res;
     940              :     }
     941      1001942 :     uint64_t q = n/30;
     942      1001942 :     uint64_t r = n%30;
     943      1001942 :     uint8_t mask;
     944      1001942 :     if(!r){mask = 0x00;}
     945       968545 :     else if(r < 7){mask = 0x01;}
     946       768148 :     else if(r < 11){mask = 0x03;}
     947       634545 :     else if(r < 13){mask = 0x07;}
     948       567752 :     else if(r < 17){mask = 0x0f;}
     949       434161 :     else if(r < 19){mask = 0x1f;}
     950       367355 :     else if(r < 23){mask = 0x3f;}
     951       233767 :     else if(r < 29){mask = 0x7f;}
     952        33391 :     else{mask = 0xff;}
     953      1001942 :     return pi_table[q-1] + __builtin_popcount(mask&~buf[q]);
     954              : }
     955              : 
     956           21 : static uint64_t *copy_small_primes(uint64_t max, uint64_t *_num_primes){
     957           21 :     uint64_t n = 0;
     958          139 :     while(n < 25 && nut_small_primes[n] <= max){
     959          118 :         ++n;
     960              :     }
     961           21 :     uint64_t *primes = malloc(n*sizeof(uint64_t));
     962           21 :     if(!primes){
     963              :         return NULL;
     964              :     }
     965           21 :     memcpy(primes, nut_small_primes, n*sizeof(uint64_t));
     966           21 :     *_num_primes = n;
     967           21 :     return primes;
     968              : }
     969              : 
     970           23 : uint64_t *nut_sieve_primes(uint64_t max, uint64_t *_num_primes){
     971           23 :     if(max <= 100){
     972           21 :         return copy_small_primes(max, _num_primes);
     973              :     }
     974            2 :     uint64_t *primes = malloc((size_t)nut_max_primes_le(max)*sizeof(uint64_t));
     975            2 :     if(!primes){
     976              :         return NULL;
     977              :     }
     978            2 :     uint8_t *is_composite = nut_sieve_is_composite(max);
     979            2 :     if(!is_composite){
     980            0 :         free(primes);
     981            0 :         return NULL;
     982              :     }
     983            2 :     memcpy(primes, nut_small_primes, 3*sizeof(uint64_t));
     984            2 :     uint64_t num_primes = 3;
     985            2 :     uint64_t q = 0;
     986            2 :     uint64_t r = 7;
     987        33368 :     while(30*q + 29 <= max){
     988        33366 :         uint8_t flags = is_composite[q];
     989        33366 :         switch(r){
     990        33364 :             case 1:
     991        33364 :                 if(!(flags & 0x1)){primes[num_primes++] = 30*q + r;}
     992        33366 :                 r = 7; [[fallthrough]];
     993        33366 :             case 7:
     994        33366 :                 if(!(flags & 0x2)){primes[num_primes++] = 30*q + r;}
     995        33366 :                 r = 11; [[fallthrough]];
     996        33366 :             case 11:
     997        33366 :                 if(!(flags & 0x4)){primes[num_primes++] = 30*q + r;}
     998        33366 :                 r = 13; [[fallthrough]];
     999        33366 :             case 13:
    1000        33366 :                 if(!(flags & 0x8)){primes[num_primes++] = 30*q + r;}
    1001        33366 :                 r = 17; [[fallthrough]];
    1002        33366 :             case 17:
    1003        33366 :                 if(!(flags & 0x10)){primes[num_primes++] = 30*q + r;}
    1004        33366 :                 r = 19; [[fallthrough]];
    1005        33366 :             case 19:
    1006        33366 :                 if(!(flags & 0x20)){primes[num_primes++] = 30*q + r;}
    1007        33366 :                 r = 23; [[fallthrough]];
    1008        33366 :             case 23:
    1009        33366 :                 if(!(flags & 0x40)){primes[num_primes++] = 30*q + r;}
    1010        33366 :                 r = 29; [[fallthrough]];
    1011        33366 :             case 29:
    1012        33366 :                 if(!(flags & 0x80)){primes[num_primes++] = 30*q + r;}
    1013              :                 r = 1;
    1014              :                 ++q;
    1015              :                 break;
    1016            0 :             default:
    1017            0 :                 __builtin_unreachable();
    1018              :         }
    1019              :     }
    1020            4 :     do{
    1021            2 :         if(30*q + 1 > max){break;}
    1022            2 :         uint8_t flags = is_composite[q];
    1023            2 :         if(!(flags & 0x1)){primes[num_primes++] = 30*q + 1;}
    1024            2 :         if(30*q + 7 > max){break;}
    1025            2 :         if(!(flags & 0x2)){primes[num_primes++] = 30*q + 7;}
    1026            2 :         if(30*q + 11 > max){break;}
    1027            0 :         if(!(flags & 0x4)){primes[num_primes++] = 30*q + 11;}
    1028            0 :         if(30*q + 13 > max){break;}
    1029            0 :         if(!(flags & 0x8)){primes[num_primes++] = 30*q + 13;}
    1030            0 :         if(30*q + 17 > max){break;}
    1031            0 :         if(!(flags & 0x10)){primes[num_primes++] = 30*q + 17;}
    1032            0 :         if(30*q + 19 > max){break;}
    1033            0 :         if(!(flags & 0x20)){primes[num_primes++] = 30*q + 19;}
    1034            0 :         if(30*q + 23 > max){break;}
    1035            0 :         if(!(flags & 0x40)){primes[num_primes++] = 30*q + 23;}
    1036              :         if(30*q + 29 > max){break;}
    1037              :         if(!(flags & 0x80)){primes[num_primes++] = 30*q + 29;}
    1038              :     }while(0);
    1039            2 :     *_num_primes = num_primes;
    1040            2 :     free(is_composite);
    1041            2 :     return realloc(primes, num_primes*sizeof(uint64_t)) ?: primes;
    1042              : }
    1043              : 
        

Generated by: LCOV version 2.0-1