#ifndef __COSMOPOLITAN__ #include #include #endif #define word unsigned long static word Null; static inline int IsTwoPow(word x) { return !(x & (x - 1)); } static inline int Bsr(word x) { #if defined(__GNUC__) && !defined(__STRICT_ANSI__) return __builtin_clzll(x) ^ 63; #else static const char kDebruijn[64] = { 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, 54, 58, 35, 52, 50, 42, 21, 44, 38, 32, 29, 23, 17, 11, 4, 62, 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43, 31, 22, 10, 45, 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63, }; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; x |= x >> 32; return kDebruijn[(x * 0x03f79d71b4cb0a89) >> 58]; #endif } static word Hash(word h, word x, word a, word b, word c) { return (((h + x) * a + b) >> c) & (Null / 2 - 1); } static word Ok(word a, word b, word c) { return Hash(Hash(Hash(0, 'L', a, b, c), 'I', a, b, c), 'N', a, b, c) == 0 && Hash(0, 'T', a, b, c) == 1 && Hash(0, 'T', a, b, c) != Hash(0, 'U', a, b, c); } static int Usage(const char *prog) { fprintf(stderr, "Usage: %s NULL\n", prog); fprintf(stderr, "Finds magic numbers for SectorLISP Hash()\n"); return 1; } int main(int argc, char *argv[]) { word a, b, c; if (argc > 1) { Null = strtoul(argv[1], 0, 0); if (Null < 64) { fprintf(stderr, "Error: Null is too small\n"); return Usage(argv[0]); } if (!IsTwoPow(Null)) { fprintf(stderr, "Error: Null must be two power\n"); return Usage(argv[0]); } } else { /* Null = 040000; */ Null = 64; } for (;; Null <<= 1) { printf("\n"); printf("#define Null %#lo\n", Null); fflush(stdout); for (a = 0; a < Null / 2; ++a) { for (c = 0; c <= Bsr(Null / 2) / 2; ++c) { /* for (b = 0; b < Null; ++b) { */ /* solve 1 = ('T' * a + b) / 2^c for b */ b = ((1<> %lu) & (Null/2-1);\n", a, b, c); } else { printf("return ((h + x) * %lu + %lu) & (Null/2-1);\n", a, b); } } } } } return 0; }