https://gcc.gnu.org/g:86a93aaef14c1597f531a826f0004c6a86e9fdd4

commit r17-2392-g86a93aaef14c1597f531a826f0004c6a86e9fdd4
Author: Tomasz Kamiński <[email protected]>
Date:   Mon Jun 1 15:31:11 2026 +0200

    libstdc++: Fix weight computation for piecewise_linear_distribution(nw, 
xmin, xmax, fw) constructor [PR125548]
    
    Compute kth weight using __fw(_M_int[k]) as required by standard,
    instead of __fw(_M_int[k] + __delta), i.e. __fw(_M_int[k + 1]).
    For __nw == 1, this was already corrected by r17-509-g7bed7d9276c11b.
    
    In both cases, previous behavior can be restored by defining
    _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS.
    
            PR libstdc++/125548
    
    libstdc++-v3/ChangeLog:
    
            * doc/html/manual/using_macros.html:
            (_GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS): Mention PR125548
            * doc/xml/manual/using.xml: Regenerate
            * include/bits/random.tcc
            (piecewise_linear_distribution::param_type::param_type(size_t, 
_RealType, ...)):
            Update weight computation.
            * 
testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc:
            Updated expected values.
            * 
testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548.cc:
            New test.
            * 
testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548_fallback.cc:
            Run pr125548.cc with _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS.
    
    Reviewed-by: Jonathan Wakely <[email protected]>
    Signed-off-by: Tomasz Kamiński <[email protected]>

Diff:
---
 libstdc++-v3/doc/html/manual/using_macros.html     |  3 +-
 libstdc++-v3/doc/xml/manual/using.xml              |  4 ++-
 libstdc++-v3/include/bits/random.tcc               | 15 ++++++++--
 .../piecewise_linear_distribution/cons/pr125548.cc | 33 ++++++++++++++++++++++
 .../cons/pr125548_fallback.cc                      |  5 ++++
 .../operators/serialize2.cc                        |  6 ++--
 6 files changed, 58 insertions(+), 8 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/using_macros.html 
b/libstdc++-v3/doc/html/manual/using_macros.html
index 10cf46436796..2e5f4b2e1a11 100644
--- a/libstdc++-v3/doc/html/manual/using_macros.html
+++ b/libstdc++-v3/doc/html/manual/using_macros.html
@@ -164,7 +164,8 @@
        is restored to their state prior the implementation
        of <a class="link" 
href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82749"; target="_top">
        PR82749</a> (<a class="link" 
href="https://cplusplus.github.io/LWG/lwg-defects.html#1439"; target="_top">
-       LWG1439</a>) in GCC 17.
+       LWG1439</a>), and <a class="link" 
href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125548"; target="_top">
+       PR125548</a>) in GCC 17.
       </p></dd><dt><span class="term"><code 
class="code">_GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES</code></span></dt><dd><p>
        Undefined by default. ABI-changing.
        When defined, specializations of
diff --git a/libstdc++-v3/doc/xml/manual/using.xml 
b/libstdc++-v3/doc/xml/manual/using.xml
index a34b8ff484a0..027b26b72cf8 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1391,7 +1391,9 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 
hello.cc -o test.exe
        xlink:href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82749";>
        PR82749</link> (<link xmlns:xlink="http://www.w3.org/1999/xlink";
        xlink:href="https://cplusplus.github.io/LWG/lwg-defects.html#1439";>
-       LWG1439</link>) in GCC 17.
+       LWG1439</link>), and <link xmlns:xlink="http://www.w3.org/1999/xlink";
+       xlink:href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125548";>
+       PR125548</link>) in GCC 17.
       </para>
     </listitem></varlistentry>
     
<varlistentry><term><code>_GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES</code></term>
diff --git a/libstdc++-v3/include/bits/random.tcc 
b/libstdc++-v3/include/bits/random.tcc
index 12c891fbbafd..bf402876eb21 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -3355,12 +3355,21 @@ namespace __detail
       {
        const size_t __n = __nw == 0 ? 1 : __nw;
        const _RealType __delta = (__xmax - __xmin) / __n;
+       const auto __cfw = [&] (_RealType __v)
+         {
+#ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
+           return __fw(__v + __delta);
+#else
+           return __fw(__v);
+#endif
+         };
+
        if (__n == 1)
          {
            _RealType __ints[2] = { __xmin, __xmin + __delta };
            _RealType __dens[2];
-           __dens[0] = __fw(__ints[0]);
-           __dens[1] = __fw(__ints[1]);
+           __dens[0] = __cfw(__ints[0]);
+           __dens[1] = __cfw(__ints[1]);
            _M_initialize2(__ints, __dens);
            return;
          }
@@ -3370,7 +3379,7 @@ namespace __detail
        for (size_t __k = 0; __k <= __nw; ++__k)
          {
            _M_int.push_back(__xmin + __k * __delta);
-           _M_den.push_back(__fw(_M_int[__k] + __delta));
+           _M_den.push_back(__cfw(_M_int[__k]));
          }
 
        _M_configure();
diff --git 
a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548.cc
 
b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548.cc
new file mode 100644
index 000000000000..2d7ae555eaa7
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548.cc
@@ -0,0 +1,33 @@
+// { dg-do run { target c++11 } }
+// { dg-require-cstdint "" }
+
+#include <random>
+#include <testsuite_hooks.h>
+
+void 
+test_functor(int n)
+{
+  const double step = 1.0/n;
+#ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS 
+  double expected = step;
+#else
+  double expected = 0.0;
+#endif
+
+  auto check_val = [&] (double value) mutable {
+    VERIFY( value == expected ); 
+    expected += step;
+    return value;
+  };
+
+  std::piecewise_linear_distribution<> d(n, 0.0, 1.0, check_val);
+}
+
+int
+main()
+{
+  test_functor(1);
+  test_functor(2);
+  test_functor(4);
+  test_functor(8);
+}
diff --git 
a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548_fallback.cc
 
b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548_fallback.cc
new file mode 100644
index 000000000000..4b8e66585700
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548_fallback.cc
@@ -0,0 +1,5 @@
+// { dg-options "-D_GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS" }
+// { dg-do run { target c++11 } }
+// { dg-require-cstdint "" }
+#include "pr125548.cc"
+
diff --git 
a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc
 
b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc
index e8ab174eb702..21365057f9ef 100644
--- 
a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc
+++ 
b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc
@@ -77,19 +77,19 @@ test_custom()
   case 24: // ieee32
     expected =
       "3 0.000000000e+00 3.333333433e-01 6.666666865e-01 1.000000000e+00"
-       " 7.272727292e-01 9.090909278e-01 1.090909061e+00 1.272727325e+00";
+       " 6.666666534e-01 8.888888977e-01 1.111111142e+00 1.333333307e+00";
     VERIFY( res == expected );
     break;
   case 53: // ieee64
     expected =
       "3 0.00000000000000000e+00 3.33333333333333315e-01 
6.66666666666666630e-01 1.00000000000000000e+00" 
-       " 7.27272727272727182e-01 9.09090909090908950e-01 
1.09090909090909083e+00 1.27272727272727249e+00";
+       " 6.66666666666666630e-01 8.88888888888888840e-01 
1.11111111111111094e+00 1.33333333333333326e+00";
     VERIFY( res == expected );
     break;
   case 64: // ieee80 
     expected =
       "3 0.000000000000000000000e+00 3.333333333333333333424e-01 
6.666666666666666666847e-01 1.000000000000000000000e+00"
-       " 7.272727272727271818908e-01 9.090909090909090606303e-01 
1.090909090909090828347e+00 1.272727272727272707087e+00";
+       " 6.666666666666666296592e-01 8.888888888888888395456e-01 
1.111111111111111160454e+00 1.333333333333333259318e+00";
     VERIFY( res == expected );
     break;
   default:

Reply via email to