[PATCH] libstdc++: Fix weight computation for piecewise_linear_distribution(nw, xmin, xmax, fw) constructor [PR125548]

Jonathan Wakely jwakely@redhat.com
Mon Jul 13 17:29:00 GMT 2026


On Mon, 01 Jun 2026 at 15:48 +0200, Tomasz Kamiński wrote:
>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_PICEWISE_DISTRIBUTIONS.

"PIECEWISE"

>
>	PR libstdc++/125548
>
>libstdc++-v3/ChangeLog:
>
>	* doc/html/manual/using_macros.html:
>	(_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS): Mention PR125548

"PIECEWISE"

>	* 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_PICEWISE_DISTRIBUTIONS.

"PIECEWISE"

OK with those typos fixed in the commit log (the patch itself is
fine). This has to wait for the densities() return type patch to be
committed though.

>---
>
>Testing on x86_64-linux. The *piecewise* test already passed.
>
> .../doc/html/manual/using_macros.html         |  5 +--
> libstdc++-v3/doc/xml/manual/using.xml         |  4 ++-
> libstdc++-v3/include/bits/random.tcc          | 15 +++++++--
> .../cons/pr125548.cc                          | 33 +++++++++++++++++++
> .../cons/pr125548_fallback.cc                 |  5 +++
> .../operators/serialize2.cc                   |  6 ++--
> 6 files changed, 59 insertions(+), 9 deletions(-)
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548.cc
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/pr125548_fallback.cc
>
>diff --git a/libstdc++-v3/doc/html/manual/using_macros.html b/libstdc++-v3/doc/html/manual/using_macros.html
>index 4be2ab576dc..2f54bf259fd 100644
>--- a/libstdc++-v3/doc/html/manual/using_macros.html
>+++ b/libstdc++-v3/doc/html/manual/using_macros.html
>@@ -156,7 +156,7 @@
> 	<code class="option">-fexec-charset=UTF-8</code> so might give incorrect results
> 	if called from a source file that uses a non-Unicode encoding,
> 	especially for format strings using non-ASCII fill characters.
>-      </p></dd><dt><span class="term"><code class="code">_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS</code></span></dt><dd><p>
>+      </p></dd><dt><span class="term"><code class="code">_GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS</code></span></dt><dd><p>
> 	Undefined by default.
> 	When defined, the behaviour specializations of
> 	<code class="code">piecewise_constant_distribution</code> and
>@@ -164,7 +164,8 @@
> 	their behavior to the 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 71fa23c24ee..1d4b32de30c 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 6c88d68d3e4..6e1ad1ef31d 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 00000000000..2d7ae555eaa
>--- /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 00000000000..4b8e6658570
>--- /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 e8ab174eb70..21365057f9e 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:
>-- 
>2.54.0
>
>



More information about the Libstdc++ mailing list