Fix PR#20843: binomial_distribution<unsigned> is broken. Add test to ensure that signed and unsigned verstions produce the same sequence.

llvm-svn: 217976
This commit is contained in:
Marshall Clow 2014-09-17 18:33:58 +00:00
parent fe357c003f
commit 3c71bff667
2 changed files with 15 additions and 1 deletions

View File

@ -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<class _IntType> template<class _IntType>
template<class _URNG> template<class _URNG>
_IntType _IntType
@ -4035,7 +4037,8 @@ binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr)
if (__u < 0) if (__u < 0)
return __rd - 1; return __rd - 1;
} }
--__rd; if ( __rd != 0 )
--__rd;
++__ru; ++__ru;
if (__ru <= __pr.__t_) if (__ru <= __pr.__t_)
{ {

View File

@ -321,6 +321,17 @@ int main()
assert(std::abs(skew - x_skew) < 0.01); assert(std::abs(skew - x_skew) < 0.01);
assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 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<unsigned> dist2(5, 0.1);
for(int i = 0; i < N; ++i)
assert(dist1(gen1) == dist2(gen2));
}
{ {
typedef std::binomial_distribution<> D; typedef std::binomial_distribution<> D;
typedef std::mt19937 G; typedef std::mt19937 G;