Patchwork [v3] libstdc++/48114

login
register
mail settings
Submitter Paolo Carlini
Date March 14, 2011, 6:27 p.m.
Message ID <4D7E5DF6.4090901@oracle.com>
Download mbox | patch
Permalink /patch/86793/
State New
Headers show

Comments

Paolo Carlini - March 14, 2011, 6:27 p.m.
Hi,

a couple of issues with the C++0x <random>, very easy to fix but very 
serious from the user point of view: due to a stupid thinko of mine we 
have been computing the binomial distribution incorrectly for p > 0.5 + 
we had the TR1 != C++0x definition for the geometric_distribution.

Both fixes applied to mainline and 4_6-branch, only the first one to 
4_5-branch.

Paolo.

///////////////
2011-03-14  Andrey Zholos  <aaz@althenia.net>

	PR libstdc++/48114
	* include/bits/random.h (geometric_distribution): Correct formula
	in comment, per C++0x.
	(geometric_distribution<>::param_type::param_type(double)): Fix check.
	(geometric_distribution<>::param_type::_M_initialize):
	Store log(1 - p).
	* include/bits/random.tcc (geometric_distribution<>::operator()):
	Fix computation.
	(binomial_distribution<>::operator()): Likewise.

Patch

Index: include/bits/random.tcc
===================================================================
--- include/bits/random.tcc	(revision 170943)
+++ include/bits/random.tcc	(working copy)
@@ -1025,7 +1025,7 @@ 
 
 	double __cand;
 	do
-	  __cand = std::ceil(std::log(__aurng()) / __param._M_log_p);
+	  __cand = std::floor(std::log(__aurng()) / __param._M_log_1_p);
 	while (__cand >= __thr);
 
 	return result_type(__cand + __naf);
@@ -1434,7 +1434,7 @@ 
       {
 	result_type __ret;
 	const _IntType __t = __param.t();
-	const _IntType __p = __param.p();
+	const double __p = __param.p();
 	const double __p12 = __p <= 0.5 ? __p : 1.0 - __p;
 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
 	  __aurng(__urng);
Index: include/bits/random.h
===================================================================
--- include/bits/random.h	(revision 170943)
+++ include/bits/random.h	(working copy)
@@ -1,6 +1,6 @@ 
 // random number generation -*- C++ -*-
 
-// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -3589,7 +3589,7 @@ 
    * @brief A discrete geometric random number distribution.
    *
    * The formula for the geometric probability density function is
-   * @f$p(i|p) = (1 - p)p^{i-1}@f$ where @f$p@f$ is the parameter of the
+   * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the
    * distribution.
    */
   template<typename _IntType = int>
@@ -3611,8 +3611,8 @@ 
 	param_type(double __p = 0.5)
 	: _M_p(__p)
 	{
-	  _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0)
-			     && (_M_p <= 1.0));
+	  _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0)
+			     && (_M_p < 1.0));
 	  _M_initialize();
 	}
 
@@ -3627,11 +3627,11 @@ 
       private:
 	void
 	_M_initialize()
-	{ _M_log_p = std::log(_M_p); }
+	{ _M_log_1_p = std::log(1.0 - _M_p); }
 
 	double _M_p;
 
-	double _M_log_p;
+	double _M_log_1_p;
       };
 
       // constructors and member function