diff mbox

[v3] libstdc++/55047

Message ID 5087DDD8.2020109@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Oct. 24, 2012, 12:23 p.m. UTC
Hi

tested x86_64-linux multilib, committed to mainline. A similar fix will 
go in 4_7-branch too.

Thanks,
Paolo.

////////////////////////
2012-10-24   Haakan Younes  <hyounes@google.com>
	     Paolo Carlini  <paolo.carlini@oracle.com>

	PR libstdc++/55047
	* include/bits/random.h (exponential_distribution<>::operator):
	Fix formula to std::log(result_type(1) - __aurng()).
	* include/bits/random.tcc: Likewise, everywhere.
diff mbox

Patch

Index: include/bits/random.tcc
===================================================================
--- include/bits/random.tcc	(revision 192718)
+++ include/bits/random.tcc	(working copy)
@@ -1,6 +1,6 @@ 
 // random number generation (out of line) -*- C++ -*-
 
-// Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 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
@@ -1187,7 +1187,7 @@ 
 
 	double __cand;
 	do
-	  __cand = std::floor(std::log(__aurng()) / __param._M_log_1_p);
+	  __cand = std::floor(std::log(1.0 - __aurng()) / __param._M_log_1_p);
 	while (__cand >= __thr);
 
 	return result_type(__cand + __naf);
@@ -1217,7 +1217,8 @@ 
 	  {
 	    double __cand;
 	    do
-	      __cand = std::floor(std::log(__aurng()) / __param._M_log_1_p);
+	      __cand = std::floor(std::log(1.0 - __aurng())
+				  / __param._M_log_1_p);
 	    while (__cand >= __thr);
 
 	    *__f++ = __cand + __naf;
@@ -1464,7 +1465,7 @@ 
 	    do
 	      {
 		const double __u = __c * __aurng();
-		const double __e = -std::log(__aurng());
+		const double __e = -std::log(1.0 - __aurng());
 
 		double __w = 0.0;
 
@@ -1496,7 +1497,7 @@ 
 		  __x = 1;
 		else
 		  {
-		    const double __v = -std::log(__aurng());
+		    const double __v = -std::log(1.0 - __aurng());
 		    const double __y = __param._M_d
 				     + __v * __2cx / __param._M_d;
 		    __x = std::ceil(__y);
@@ -1655,7 +1656,7 @@ 
 
 	do
 	  {
-	    const double __e = -std::log(__aurng());
+	    const double __e = -std::log(1.0 - __aurng());
 	    __sum += __e / (__t - __x);
 	    __x += 1;
 	  }
@@ -1723,7 +1724,7 @@ 
 		    __reject = __y >= __param._M_d1;
 		    if (!__reject)
 		      {
-			const double __e = -std::log(__aurng());
+			const double __e = -std::log(1.0 - __aurng());
 			__x = std::floor(__y);
 			__v = -__e - __n * __n / 2 + __param._M_c;
 		      }
@@ -1735,15 +1736,15 @@ 
 		    __reject = __y >= __param._M_d2;
 		    if (!__reject)
 		      {
-			const double __e = -std::log(__aurng());
+			const double __e = -std::log(1.0 - __aurng());
 			__x = std::floor(-__y);
 			__v = -__e - __n * __n / 2;
 		      }
 		  }
 		else if (__u <= __a123)
 		  {
-		    const double __e1 = -std::log(__aurng());
-		    const double __e2 = -std::log(__aurng());
+		    const double __e1 = -std::log(1.0 - __aurng());
+		    const double __e2 = -std::log(1.0 - __aurng());
 
 		    const double __y = __param._M_d1
 				     + 2 * __s1s * __e1 / __param._M_d1;
@@ -1754,8 +1755,8 @@ 
 		  }
 		else
 		  {
-		    const double __e1 = -std::log(__aurng());
-		    const double __e2 = -std::log(__aurng());
+		    const double __e1 = -std::log(1.0 - __aurng());
+		    const double __e2 = -std::log(1.0 - __aurng());
 
 		    const double __y = __param._M_d2
 				     + 2 * __s2s * __e1 / __param._M_d2;
@@ -1869,7 +1870,7 @@ 
 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
 	  __aurng(__urng);
 	while (__f != __t)
-	  *__f++ = -std::log(__aurng()) / __p.lambda();
+	  *__f++ = -std::log(result_type(1) - __aurng()) / __p.lambda();
       }
 
   template<typename _RealType, typename _CharT, typename _Traits>
@@ -2628,7 +2629,7 @@ 
       {
 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
 	  __aurng(__urng);
-	return __p.b() * std::pow(-std::log(__aurng()),
+	return __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
 				  result_type(1) / __p.a());
       }
 
@@ -2644,10 +2645,11 @@ 
 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
 	  __aurng(__urng);
-	auto inv_a = result_type(1) / __p.a();
+	auto __inv_a = result_type(1) / __p.a();
 
 	while (__f != __t)
-	  *__f++ = __p.b() * std::pow(-std::log(__aurng()), inv_a);
+	  *__f++ = __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
+				      __inv_a);
       }
 
   template<typename _RealType, typename _CharT, typename _Traits>
@@ -2704,7 +2706,8 @@ 
       {
 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
 	  __aurng(__urng);
-	return __p.a() - __p.b() * std::log(-std::log(__aurng()));
+	return __p.a() - __p.b() * std::log(-std::log(result_type(1)
+						      - __aurng()));
       }
 
   template<typename _RealType>
@@ -2721,7 +2724,8 @@ 
 	  __aurng(__urng);
 
 	while (__f != __t)
-	  *__f++ = __p.a() - __p.b() * std::log(-std::log(__aurng()));
+	  *__f++ = __p.a() - __p.b() * std::log(-std::log(result_type(1)
+							  - __aurng()));
       }
 
   template<typename _RealType, typename _CharT, typename _Traits>
Index: include/bits/random.h
===================================================================
--- include/bits/random.h	(revision 192718)
+++ include/bits/random.h	(working copy)
@@ -1,6 +1,6 @@ 
 // random number generation -*- C++ -*-
 
-// Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 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
@@ -4748,7 +4748,7 @@ 
 	{
 	  __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
 	    __aurng(__urng);
-	  return -std::log(__aurng()) / __p.lambda();
+	  return -std::log(result_type(1) - __aurng()) / __p.lambda();
 	}
 
       template<typename _ForwardIterator,