From 07bba3b144e10e4296154f34a405b12d6af33798 Mon Sep 17 00:00:00 2001
From: Paolo Carlini <paolo.carlini@oracle.com>
Date: Sat, 22 Jun 2013 21:07:02 +0000
Subject: [PATCH] re PR libstdc++/57674 (wrong distribution for 
 std::binomial_distribution::operator()(g,param))

2013-06-22  Paolo Carlini  <paolo.carlini@oracle.com>

	PR libstdc++/57674
	* include/bits/random.h (binomial_distribution<>::_M_waiting):
	Add double parameter.
	* include/bits/random.tcc (binomial_distribution<>::operator()
	(_UniformRandomNumberGenerator&, const param_type&)): Pass
	__param._M_q to _M_waiting.
	(_M_waiting): Adjust.
	* testsuite/26_numerics/random/binomial_distribution/
	operators/values.cc: Add tests.

From-SVN: r200341
---
 libstdc++-v3/ChangeLog                               | 12 ++++++++++++
 libstdc++-v3/include/bits/random.h                   |  3 ++-
 libstdc++-v3/include/bits/random.tcc                 | 10 ++++++----
 .../random/binomial_distribution/operators/values.cc | 11 +++++++++++
 4 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 6a92f61c588e..bff4008ab348 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,15 @@
+2013-06-22  Paolo Carlini  <paolo.carlini@oracle.com>
+
+	PR libstdc++/57674
+	* include/bits/random.h (binomial_distribution<>::_M_waiting):
+	Add double parameter.
+	* include/bits/random.tcc (binomial_distribution<>::operator()
+	(_UniformRandomNumberGenerator&, const param_type&)): Pass
+	__param._M_q to _M_waiting.
+	(_M_waiting): Adjust.
+	* testsuite/26_numerics/random/binomial_distribution/
+	operators/values.cc: Add tests.
+
 2013-06-21  Paolo Carlini  <paolo.carlini@oracle.com>
 
 	PR libstdc++/57666
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index b471726be556..caabe906058b 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -3978,7 +3978,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       template<typename _UniformRandomNumberGenerator>
 	result_type
-	_M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
+	_M_waiting(_UniformRandomNumberGenerator& __urng,
+		   _IntType __t, double __q);
 
       param_type _M_param;
 
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
index 5b562b9f270d..c6db5b40cb70 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -1648,7 +1648,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template<typename _UniformRandomNumberGenerator>
       typename binomial_distribution<_IntType>::result_type
       binomial_distribution<_IntType>::
-      _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t)
+      _M_waiting(_UniformRandomNumberGenerator& __urng,
+		 _IntType __t, double __q)
       {
 	_IntType __x = 0;
 	double __sum = 0.0;
@@ -1663,7 +1664,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    __sum += __e / (__t - __x);
 	    __x += 1;
 	  }
-	while (__sum <= _M_param._M_q);
+	while (__sum <= __q);
 
 	return __x - 1;
       }
@@ -1784,12 +1785,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 	    __x += __np + __naf;
 
-	    const _IntType __z = _M_waiting(__urng, __t - _IntType(__x));
+	    const _IntType __z = _M_waiting(__urng, __t - _IntType(__x),
+					    __param._M_q);
 	    __ret = _IntType(__x) + __z;
 	  }
 	else
 #endif
-	  __ret = _M_waiting(__urng, __t);
+	  __ret = _M_waiting(__urng, __t, __param._M_q);
 
 	if (__p12 != __p)
 	  __ret = __t - __ret;
diff --git a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/operators/values.cc b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/operators/values.cc
index 89e84ca56816..4633a060e685 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/operators/values.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/operators/values.cc
@@ -43,6 +43,17 @@ void test01()
   std::binomial_distribution<> bd3(10, 0.75);
   auto bbd3 = std::bind(bd3, eng);
   testDiscreteDist(bbd3, [](int n) { return binomial_pdf(n, 10, 0.75); } );
+
+  // libstdc++/57674
+  std::binomial_distribution<> bd4(1, 0.8);
+  const std::binomial_distribution<>::param_type pm4(1, 0.3);
+  auto bbd4 = std::bind(bd4, eng, pm4);
+  testDiscreteDist(bbd4, [](int n) { return binomial_pdf(n, 1, 0.3); } );
+
+  std::binomial_distribution<> bd5(100, 0.3);
+  const std::binomial_distribution<>::param_type pm5(100, 0.8);
+  auto bbd5 = std::bind(bd5, eng, pm5);
+  testDiscreteDist(bbd5, [](int n) { return binomial_pdf(n, 100, 0.8); } );
 }
 
 int main()
-- 
GitLab