This patch changes how linear_congruential_engine picks its randomization algorithm. It adds two restrictions, _OverflowOK and _SchrageOK. _OverflowOK means that m is a power of two so using the classic (a * x + c) % m will create a meaningless overflow. The second checks that Schrage's algorithm will produce results that are in bounds of min and max. This patch fixes 27839.
Details
- Reviewers
mclow.lists ldionne EricWF - Group Reviewers
Restricted Project - Commits
- rG31dfaff3b395: [libc++] Change requirements on linear_congruential_engine.
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I think it may be good to remove Schrage's algorithm altogether and file an LWG issue for the remaining edge cases. It is very slow and feels out of place in LCG. Additionally, Schrage's algorithm introduces lot's of added complexity and space for bugs.
libcxx/include/random | ||
---|---|---|
1676 | This static_assert is redundant. Maybe I should remove it. |
libcxx/include/random | ||
---|---|---|
1676 | Can this be simplified to static_assert(!_MightOverflow || _OverflowOK || _ShrageOk, "");? |
libcxx/include/random | ||
---|---|---|
1676 | Yep :) Thanks. |
LGTM after fixing the nitpicks. For full disclosure, I'm relying on the tests a lot here because I am *not* a PRNG expert and I didn't take hours to research the algorithms in use. I'm trusting that you did look at other state of the art.
libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/alg.pass.cpp | ||
---|---|---|
68 | Inconsistent indentation here. | |
libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/params.fail.cpp | ||
17 | Not needed. | |
19 | Not needed. | |
33 | Same. |
For full disclosure, I'm relying on the tests a lot here because I am *not* a PRNG expert and I didn't take hours to research the algorithms in use. I'm trusting that you did look at other state of the art.
Neither am I. Not sure what you mean by "state of the art." I mainly went off the discussion of the bug and various online guides. An important note: this only changes how we pick what algorithm to use, it doesn't change any of the algorithms themselves.
Anyway, I'll fix the comments and land this.
This static_assert is redundant. Maybe I should remove it.