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  <hyou...@google.com>
             Paolo Carlini  <paolo.carl...@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.
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,

Reply via email to