header.c (2988B)
1 /** 2 * Precomputer for metaprogramming generated precomputed.h header 3 * file that is useful. 4 */ 5 #include <flint.h> 6 #include <fmpz.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 10 #include <assert.h> 11 12 #define SMALLPRIME_LIMIT (1<<16) 13 14 static slong 15 calc_len(fmpz_t n) 16 { 17 assert(fmpz_cmp_ui(n, 0) > 0); 18 return (slong) fmpz_size(n); 19 } 20 21 static void 22 pparray(FILE* f, const ulong *a, const slong len) 23 { 24 slong i; 25 for(i = 0; i < len; i++) { 26 if(i == 0) { 27 fprintf(f, " "); 28 } else if(i % 8 == 0) { 29 fprintf(f, "\n "); 30 } 31 fprintf(f, "0x%016lx, ", a[i]); 32 } 33 } 34 35 // ugly, but okay for precomputer 36 static size_t 37 count_smallprimes(size_t limit) 38 { 39 fmpz_t p; 40 fmpz_init_set_ui(p, 2); 41 size_t i = 0; 42 43 while (fmpz_cmp_ui(p, limit) < 0) { 44 fmpz_nextprime(p, p, 0); 45 i++; 46 } 47 fmpz_clear(p); 48 49 return i; 50 } 51 52 static void 53 print_disclaimer(FILE* f) 54 { 55 fprintf(f, "/**\n" 56 " * This file has been automatically computed using the\n" 57 " * precompute/header utility. The purpose is to store\n" 58 " * some constant values, such as\n" 59 " *\n" 60 " * - limbs of a primorial (product of small primes)\n" 61 " * - list of small primes\n" 62 " */\n\n"); 63 } 64 65 int 66 main(void) 67 { 68 // -= header file =- 69 70 fmpz_t primorial; 71 fmpz_init(primorial); 72 73 fmpz_primorial(primorial, 1 << 16); 74 75 slong len = calc_len(primorial); 76 ulong *out = malloc(len * sizeof(*out)); 77 78 fmpz_get_ui_array(out, len, primorial); 79 80 FILE* header = fopen("/tmp/precomputed.h", "w"); 81 fprintf(header, "// --------------- precomputed.h ---------------------\n"); 82 fprintf(header, "#ifndef PRECOMPUTED_H\n" 83 "#define PRECOMPUTED_H\n\n"); 84 print_disclaimer(header); 85 fprintf(header, "#include <flint.h>\n\n"); 86 87 fprintf(header, "#define PC_PRIMORIAL_UI_ARRAY_LEN %ld\n", len); 88 fprintf(header, "#define PC_SMALLPRIMES_LEN %ld\n\n", 89 count_smallprimes(SMALLPRIME_LIMIT)); 90 fprintf(header, "extern const ulong " 91 "pc_primorial_ui_array[PC_PRIMORIAL_UI_ARRAY_LEN];\n" 92 "extern const ulong " 93 "pc_smallprimes[PC_SMALLPRIMES_LEN];\n" 94 "#endif\n\n"); 95 fclose(header); 96 97 // -= source file =- 98 99 FILE* source = fopen("/tmp/precomputed.c", "w"); 100 fprintf(source, "// ------------- precomputed.c ------------------------\n"); 101 102 print_disclaimer(source); 103 fprintf(source, "#include \"precomputed.h\"\n"); 104 fprintf(source, "const ulong " 105 "pc_primorial_ui_array[PC_PRIMORIAL_UI_ARRAY_LEN] = {\n"); 106 pparray(source, out, len); 107 fprintf(source, "};\n\n"); 108 109 fmpz_clear(primorial); 110 free(out); 111 112 // -= small primes =- 113 114 fmpz_t p; 115 fmpz_init_set_ui(p, 2); 116 size_t i = 0; 117 118 fprintf(source, "const ulong pc_smallprimes[PC_SMALLPRIMES_LEN] = {\n"); 119 while (fmpz_cmp_ui(p, (1 << 16)) < 0) { 120 if (i == 0) { 121 fprintf(source, " "); 122 } else if (i % 8 == 0) { 123 fprintf(source, "\n "); 124 } 125 126 fmpz_fprint(source, p); 127 fprintf(source, ", "); 128 129 fmpz_nextprime(p, p, 0); 130 131 i++; 132 } 133 fprintf(source, "};\n\n"); 134 135 fclose(source); 136 fmpz_clear(p); 137 138 return 0; 139 }