From 5ffb8d0fbee0fb591646674f28bc54ed9dc16e43 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Wed, 17 Sep 2014 18:33:58 +0000 Subject: [PATCH] Fix PR#20843: binomial_distribution is broken. Add test to ensure that signed and unsigned verstions produce the same sequence. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@217976 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/random | 5 ++++- .../rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/random b/include/random index c0db1abac..e7053ce4e 100644 --- a/include/random +++ b/include/random @@ -4009,6 +4009,8 @@ binomial_distribution<_IntType>::param_type::param_type(result_type __t, double } } +// Reference: Kemp, C.D. (1986). `A modal method for generating binomial +// variables', Commun. Statist. - Theor. Meth. 15(3), 805-813. template template _IntType @@ -4035,7 +4037,8 @@ binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr) if (__u < 0) return __rd - 1; } - --__rd; + if ( __rd != 0 ) + --__rd; ++__ru; if (__ru <= __pr.__t_) { diff --git a/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp b/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp index 3bfd2af61..85ff2ac47 100644 --- a/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp +++ b/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp @@ -321,6 +321,17 @@ int main() assert(std::abs(skew - x_skew) < 0.01); assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01); } + { + const int N = 100000; + std::mt19937 gen1; + std::mt19937 gen2; + + std::binomial_distribution<> dist1(5, 0.1); + std::binomial_distribution dist2(5, 0.1); + + for(int i = 0; i < N; ++i) + assert(dist1(gen1) == dist2(gen2)); + } { typedef std::binomial_distribution<> D; typedef std::mt19937 G;