https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88849
Zhang Boyang <zhangboyang.id at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |zhangboyang.id at gmail dot com --- Comment #1 from Zhang Boyang <zhangboyang.id at gmail dot com> --- Hi, I think I encountered the same bug. I did 10000000000 tests of B(N=100,P=0.15) and I observed the "weighted average" was about 15.004, which is about 0.004 larger than the "expected value" (N*P=15). This behavior is not observed if the naive method (i.e. run std::bernoulli_distribution(P) for N times) is used. Thus I think this indicates there is a bug in the implementation of std::binomial_distribution. Zhang Boyang My test program is: #include <cstdio> #include <random> #define N 100 #define P 0.15 #define OUTER_LOOP 10000 #define INNER_LOOP 1000000 int main() { long long result[N+1] = {}; #if 1 std::mt19937 gen(20240201); #else std::mt19937_64 gen(20240201); #endif for (int i = 1; i <= OUTER_LOOP; i++) { #if 1 std::binomial_distribution<int> d(N, P); for (int j = 1; j <= INNER_LOOP; j++) { result[d(gen)]++; } #else std::bernoulli_distribution d(P); for (int j = 1; j <= INNER_LOOP; j++) { int cur = 0; for (int k = 1; k <= N; k++) { cur += d(gen); } result[cur]++; } #endif long long cnt = 0, sum = 0; for (int j = 0; j <= N; j++) { cnt += result[j]; sum += j * result[j]; } printf("%d/%d\n", i, OUTER_LOOP); for (int j = 0; j <= N; j++) { printf("%5d %20lld %.20f\n", j, result[j], (double)result[j]/cnt); } printf("%d/%d\n", i, OUTER_LOOP); printf(" cnt = %lld\n", cnt); printf(" sum = %lld\n", sum); printf(" avg = %.20f\n", (double)sum/cnt); printf(" N*P = %.20f\n", N*P); printf("avg/N = %.20f\n", (double)sum/cnt/N); printf(" P = %.20f\n", P); } return 0; } The result is: cnt = 10000000000 sum = 150039073251 avg = 15.00390732510000013633 N*P = 15.00000000000000000000 avg/N = 0.15003907325099999359 P = 0.14999999999999999445 The histogram is: 0 930 0.00000009300000000000 1 15401 0.00000154010000000000 2 135116 0.00001351160000000000 3 779486 0.00007794859999999999 4 3329355 0.00033293549999999998 5 11293727 0.00112937270000000004 6 31552023 0.00315520229999999985 7 74764087 0.00747640870000000016 8 153388141 0.01533881410000000056 9 276729436 0.02767294359999999953 10 444347696 0.04443476960000000003 11 640022574 0.06400225739999999830 12 834915008 0.08349150079999999308 13 996435535 0.09964355349999999556 14 1094566902 0.10945669019999999805 15 1112943209 0.11129432089999999334 16 1043376263 0.10433762629999999982 17 909811402 0.09098114020000000468 18 740331472 0.07403314719999999627 19 563856817 0.05638568170000000240 20 402991697 0.04029916969999999821 21 270919911 0.02709199110000000063 22 171678195 0.01716781950000000057 23 102734220 0.01027342200000000080 24 58150147 0.00581501470000000010 25 31216233 0.00312162330000000012 26 15892051 0.00158920510000000004 27 7686873 0.00076868729999999999 28 3531666 0.00035316660000000001 29 1548848 0.00015488479999999999 30 646371 0.00006463710000000000 31 257351 0.00002573510000000000 32 98083 0.00000980830000000000 33 35443 0.00000354430000000000 34 12256 0.00000122560000000000 35 4202 0.00000042020000000000 36 1320 0.00000013200000000000 37 396 0.00000003960000000000 38 118 0.00000001180000000000 39 30 0.00000000300000000000 40 9 0.00000000090000000000 41 0 0.00000000000000000000 42 0 0.00000000000000000000 43 0 0.00000000000000000000 44 0 0.00000000000000000000 45 0 0.00000000000000000000 46 0 0.00000000000000000000 47 0 0.00000000000000000000 48 0 0.00000000000000000000 49 0 0.00000000000000000000 50 0 0.00000000000000000000 51 0 0.00000000000000000000 52 0 0.00000000000000000000 53 0 0.00000000000000000000 54 0 0.00000000000000000000 55 0 0.00000000000000000000 56 0 0.00000000000000000000 57 0 0.00000000000000000000 58 0 0.00000000000000000000 59 0 0.00000000000000000000 60 0 0.00000000000000000000 61 0 0.00000000000000000000 62 0 0.00000000000000000000 63 0 0.00000000000000000000 64 0 0.00000000000000000000 65 0 0.00000000000000000000 66 0 0.00000000000000000000 67 0 0.00000000000000000000 68 0 0.00000000000000000000 69 0 0.00000000000000000000 70 0 0.00000000000000000000 71 0 0.00000000000000000000 72 0 0.00000000000000000000 73 0 0.00000000000000000000 74 0 0.00000000000000000000 75 0 0.00000000000000000000 76 0 0.00000000000000000000 77 0 0.00000000000000000000 78 0 0.00000000000000000000 79 0 0.00000000000000000000 80 0 0.00000000000000000000 81 0 0.00000000000000000000 82 0 0.00000000000000000000 83 0 0.00000000000000000000 84 0 0.00000000000000000000 85 0 0.00000000000000000000 86 0 0.00000000000000000000 87 0 0.00000000000000000000 88 0 0.00000000000000000000 89 0 0.00000000000000000000 90 0 0.00000000000000000000 91 0 0.00000000000000000000 92 0 0.00000000000000000000 93 0 0.00000000000000000000 94 0 0.00000000000000000000 95 0 0.00000000000000000000 96 0 0.00000000000000000000 97 0 0.00000000000000000000 98 0 0.00000000000000000000 99 0 0.00000000000000000000 100 0 0.00000000000000000000 Compiler information (archlinux gcc-13.2.1-4): Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /build/gcc/src/gcc/configure --enable-languages=ada,c,c++,d,fortran,go,lto,m2,objc,obj-c++ --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 13.2.1 20230801 (GCC)