Date: Fri, 5 Dec 2025 12:31:55 +0000
On Fri, 5 Dec 2025 at 12:17, Jonathan Wakely <cxx_at_[hidden]> wrote:
> On Fri, 5 Dec 2025 at 11:03, Juan Lucas Rey wrote:
>
>> Hello,
>>
>> Here is an example code that shows:
>>
>> -the original issue reproduced as shown in
>> https://cplusplus.github.io/LWG/issue2524
>
>
> For anybody else trying it, the original problem can be reproduced with
> libc++ but not libstdc++, because libstdc++ has a workaround in
> std::generate_canonical which returns the largest value of RealType which
> is less than RealType(1).
>
>
>>
>> - std2::exponential_distribution, using internally
>> std2::generate_canonical_centered and NOT showing the issue
>> -other values are the same
>>
>> I have added a double template parameter "limit" to
>> "std2::generate_canonical_centered". to allow maximum backwards
>> compatibility, that value should be close to 1.
>> setting that value to 0.5 is maybe more elegant, but less backward
>> compatible.
>>
>
> So it's just a hardcoded "use a different calculation if the result would
> be greater than LIMIT" branch inside generate_canonical_centred. OK. But
> isn't that alternative path taken for a tiny fraction of the values from
> the URNG? Something like 1e-8 of the full range? So it's not symmetrical
> around zero? Instead it seems to return values in the range [-1e-08, 1.0).
>
> I thought the proposal was for a symmetric distribution around zero? So I
> think I'm failing to understand the proposal.
>
Also, is that 'limit' parameter actually part of the proposal? Because it
wasn't shown in the original PDF you sent, but it seems to be necessary to
offer the backwards compatibility which is mentioned in the PDF and in your
original email.
>
> I'm not sure how very occasionally returning values below zero, i.e. below
> the expected range of [0,1), is better than very occasionally returning
> 1.0, i.e. above the expected range.
>
> So again, I think the idea of an alternative function that is symmetrical
> around zero is interesting. But I don't understand the backwards
> compatibility argument at all. It seems that your solution returns the same
> values as the old spec for std::generate_canonical in most cases, but just
> has a different form of failure in the problematic cases. Sure, we can
> adjust std::exponential_distribution to cope with the "bad" results, but
> std::generate_canonical_centred with a limit of 0.999999 is not centred,
> and fails to meet the original contract for std::generate_canonical.
>
> Unless I'm misunderstanding something, I think this proposal would make
> more sense if you dropped the backwards compatibility claims, and just
> demonstrated why a symmetric-around-zero distribution has valuable
> properties. But you should also show how it would be used by the rest of
> the library. You've shown how std::exponential_distribution can be adapted
> to work with (-0.5,0.5] but what about std::uniform_real_distribution and
> std::bernoulli_distribution, etc. I count 26 uses of generate_canonical in
> libstdc++'s <random>, should they all be changed to use
> generate_canonical_centred? Wouldn't that mean an extra branch and extra
> logic in every one of them, to handle the negative half of the range? Or
> maybe there's no benefit to some distributions and they should continue to
> use std::generate_canonical? I think the proposal needs to explain the
> extent of the changes that would result from introducing this new function.
>
In other words, if the proposal is to allow std::generate_canonical_centred
to be customized by callers (but maybe default to 0.5 so it's actually
centred around zero?), how would that work for all the existing callers
inside the std::lib? If the idea is to allow users to select an algorithm
that's backwards compatible with the old spec (so that re-running
simulations produces the same results as with the old spec), how would
users select that when most uses of std::generate_canonical are hidden
inside std::xxx_distribution and are not exposed to users directly?
tl;dr who are the expected users of this new function, and how exactly
would it benefit them?
>
> Or maybe I'm just misunderstanding something ... in which case that
> suggests something in the proposal needs to be clarified.
>
>
>
> On Fri, 5 Dec 2025 at 11:03, Juan Lucas Rey wrote:
>
>> Hello,
>>
>> Here is an example code that shows:
>>
>> -the original issue reproduced as shown in
>> https://cplusplus.github.io/LWG/issue2524
>
>
> For anybody else trying it, the original problem can be reproduced with
> libc++ but not libstdc++, because libstdc++ has a workaround in
> std::generate_canonical which returns the largest value of RealType which
> is less than RealType(1).
>
>
>>
>> - std2::exponential_distribution, using internally
>> std2::generate_canonical_centered and NOT showing the issue
>> -other values are the same
>>
>> I have added a double template parameter "limit" to
>> "std2::generate_canonical_centered". to allow maximum backwards
>> compatibility, that value should be close to 1.
>> setting that value to 0.5 is maybe more elegant, but less backward
>> compatible.
>>
>
> So it's just a hardcoded "use a different calculation if the result would
> be greater than LIMIT" branch inside generate_canonical_centred. OK. But
> isn't that alternative path taken for a tiny fraction of the values from
> the URNG? Something like 1e-8 of the full range? So it's not symmetrical
> around zero? Instead it seems to return values in the range [-1e-08, 1.0).
>
> I thought the proposal was for a symmetric distribution around zero? So I
> think I'm failing to understand the proposal.
>
Also, is that 'limit' parameter actually part of the proposal? Because it
wasn't shown in the original PDF you sent, but it seems to be necessary to
offer the backwards compatibility which is mentioned in the PDF and in your
original email.
>
> I'm not sure how very occasionally returning values below zero, i.e. below
> the expected range of [0,1), is better than very occasionally returning
> 1.0, i.e. above the expected range.
>
> So again, I think the idea of an alternative function that is symmetrical
> around zero is interesting. But I don't understand the backwards
> compatibility argument at all. It seems that your solution returns the same
> values as the old spec for std::generate_canonical in most cases, but just
> has a different form of failure in the problematic cases. Sure, we can
> adjust std::exponential_distribution to cope with the "bad" results, but
> std::generate_canonical_centred with a limit of 0.999999 is not centred,
> and fails to meet the original contract for std::generate_canonical.
>
> Unless I'm misunderstanding something, I think this proposal would make
> more sense if you dropped the backwards compatibility claims, and just
> demonstrated why a symmetric-around-zero distribution has valuable
> properties. But you should also show how it would be used by the rest of
> the library. You've shown how std::exponential_distribution can be adapted
> to work with (-0.5,0.5] but what about std::uniform_real_distribution and
> std::bernoulli_distribution, etc. I count 26 uses of generate_canonical in
> libstdc++'s <random>, should they all be changed to use
> generate_canonical_centred? Wouldn't that mean an extra branch and extra
> logic in every one of them, to handle the negative half of the range? Or
> maybe there's no benefit to some distributions and they should continue to
> use std::generate_canonical? I think the proposal needs to explain the
> extent of the changes that would result from introducing this new function.
>
In other words, if the proposal is to allow std::generate_canonical_centred
to be customized by callers (but maybe default to 0.5 so it's actually
centred around zero?), how would that work for all the existing callers
inside the std::lib? If the idea is to allow users to select an algorithm
that's backwards compatible with the old spec (so that re-running
simulations produces the same results as with the old spec), how would
users select that when most uses of std::generate_canonical are hidden
inside std::xxx_distribution and are not exposed to users directly?
tl;dr who are the expected users of this new function, and how exactly
would it benefit them?
>
> Or maybe I'm just misunderstanding something ... in which case that
> suggests something in the proposal needs to be clarified.
>
>
>
Received on 2025-12-05 12:32:14
