#include #include #include #include static void analyze(unsigned char *Vc, size_t n) { static uint64_t Vmap[0x100000000 / 64]; static uint64_t Vmap_lo[0x10000 / 64], Vmap_hi[0x10000 / 64]; static int called; uint32_t *Vi = (uint32_t *)Vc; size_t i; size_t counts[0x100], min, max, diff, diff_lo, diff_hi; fprintf(stderr, "n = %llu\n", (unsigned long long)n); memset(counts, 0, sizeof(counts)); for (i = 0; i < n; i++) counts[Vc[i]]++; min = ~0UL; max = 0; for (i = 0; i < 0x100; i++) { if (min > counts[i]) min = counts[i]; if (max < counts[i]) max = counts[i]; } fprintf(stderr, "min = %llu max = %llu" " (min+max)/2 = %.1f (expected %.1f)\n", (unsigned long long)min, (unsigned long long)max, (double)(min + max) / 2.0, (double)n / 0x100); n /= sizeof(uint32_t); /* Assume the statics are zero on first call */ if (called) { memset(Vmap, 0, sizeof(Vmap)); memset(Vmap_lo, 0, sizeof(Vmap_lo)); memset(Vmap_hi, 0, sizeof(Vmap_hi)); } called = 1; diff = diff_lo = diff_hi = 0; for (i = 0; i < n; i++) { uint32_t x = Vi[i]; uint32_t lo = x & 0xffff; uint32_t hi = x >> 16; uint64_t * v = &Vmap[x / 64]; if (!(*v & ((uint64_t)1 << (x % 64)))) diff++; *v |= (uint64_t)1 << (x % 64); v = &Vmap_lo[lo / 64]; if (!(*v & ((uint64_t)1 << (lo % 64)))) diff_lo++; *v |= (uint64_t)1 << (lo % 64); v = &Vmap_hi[hi / 64]; if (!(*v & ((uint64_t)1 << (hi % 64)))) diff_hi++; *v |= (uint64_t)1 << (hi % 64); } fprintf(stderr, "diff = %llu (expected %.1f)\n" "diff_lo = %llu diff_hi = %llu (expected %.1f)\n", (unsigned long long)diff, (1ULL << 32) * (1.0 - pow(((1ULL << 32) - 1.0) / (1ULL << 32), n)), (unsigned long long)diff_lo, (unsigned long long)diff_hi, 0x10000 * (1.0 - pow((0x10000 - 1.0) / 0x10000, n))); } int main(void) { static unsigned char V[0x10000000]; size_t n; n = fread(V, 1, sizeof(V), stdin); if (ferror(stdin)) { perror("fread"); return 1; } analyze(V, n); return 0; }