This article is rated Start-class on Wikipedia's
content assessment scale. It is of interest to the following WikiProjects: | ||||||||||||||
|
On 1 July 2023, it was proposed that this article be moved from ACORN (PRNG) to ACORN (random number generator). The result of the discussion was moved. |
Do any editors here have a wp:coi? Slatersteven ( talk) 16:54, 6 April 2022 (UTC)
The result of the move request was: moved. ( non-admin closure) {{replyto| SilverLocust}} ( talk) 01:27, 8 July 2023 (UTC)
ACORN (PRNG) → ACORN (random number generator) – Disambiguators should be intelligible to the common reader, not jargon. * Pppery * it has begun... 00:04, 1 July 2023 (UTC)
Hello! I've wanted to to give this PRNG a try before, but the current example code is somewhat impenetrable. I ran it through chatgpt to get a C translation, which I then turned into a C++11 implementation. It looks like this (i have no idea how to format it on this page):
// State array of arbitrary size.
// The first element must be odd, the other elements can be randomly set.
std::array<uint64_t, 16> state {
0xE907505CB59C77D1, 0x8D6CA05F581DA875, 0x66F0C7ABEDA8D656, 0xEA0FF0093C2D3AB4,
0x48DE7C3E7FA5F645, 0xDF816A1E4941B30E, 0x28FF5C18C591C8B2, 0xD86AB519D00D93E1,
0x7D1A153C980DEA8A, 0xAFF20955CB3FFC46, 0xA63707C164CD19F4, 0x953458E388B9020C,
0xCFCA87EBA0626046, 0x1E9AF6B90B7EBF91, 0xE86BDCAAE59D8EDA, 0xD0B78E2AD9B6C63D,
};
uint32_t acorn_u32() {
// Update the current element by adding the previous element to it.
// Note: the first element is never updated.
for(int x = 1; x < state.size(); ++x) {
state[x] += state[x - 1];
}
// Return the high bits of the last element of the array.
return state.back() >> 32;
}
Does this seem fit for inclusion?
Notes:
Unlike the current example which generates 64 bits and turns it into a double precision float, this code simply generates 32 bits (should maybe be even less? see below).
Also, I'm pretty sure the float generation method used in the fortran example code (division by modulus) introduces bias and besides, it isn't strictly part of the PRNG so I left it out.
Something else that doesn't seem to be mentioned anywhere is that the lower bits are of poor quality. Returning the full 64-bit element quickly fails PractRand's tests. I wanted to make sure I didn't do anything wrong so I searched around and found these polish forum posts (used google translate to read): [1]. This person realized the same thing: casting the generated bits to a double float will discard some of the lower bits and mask the problem, but it's not exactly spelled out very clearly.
Now, the C++ example code outputs 32 bits and will actually fail PractRand pretty early as well... to avoid this, 128 bit elements could be used or the output could be smaller (24 bits seem fine but isn't a convenient size, so the next step is 16 bits). I'm not a fan of either really, but if we would like the example to not fail PractRand early I'd maybe go with 16 bit output as 128 bit integers aren't super common (I think?).
Quick aside... I think everyone already knows, but the article was clearly written by someone with vested interest, haha. Fred Underscore ( talk) 09:07, 5 July 2023 (UTC)
<syntaxhighlight lang="c++">...</syntaxhighlight>
which would give:// State array of arbitrary size.
// The first element must be odd, the other elements can be randomly set.
std::array<uint64_t, 16> state {
0xE907505CB59C77D1, 0x8D6CA05F581DA875, 0x66F0C7ABEDA8D656, 0xEA0FF0093C2D3AB4,
0x48DE7C3E7FA5F645, 0xDF816A1E4941B30E, 0x28FF5C18C591C8B2, 0xD86AB519D00D93E1,
0x7D1A153C980DEA8A, 0xAFF20955CB3FFC46, 0xA63707C164CD19F4, 0x953458E388B9020C,
0xCFCA87EBA0626046, 0x1E9AF6B90B7EBF91, 0xE86BDCAAE59D8EDA, 0xD0B78E2AD9B6C63D,
};
uint32_t acorn_u32() {
// Update the current element by adding the previous element to it.
// Note: the first element is never updated.
for(int x = 1; x < state.size(); ++x) {
statex += statex - 1];
}
// Return the high bits of the last element of the array.
return state.back() >> 32;
}
::::// State array of arbitrary size.
::::// The first element must be odd, the other elements can be randomly set.
::::std::array<uint64_t, 16> state {};
::::
This article is rated Start-class on Wikipedia's
content assessment scale. It is of interest to the following WikiProjects: | ||||||||||||||
|
On 1 July 2023, it was proposed that this article be moved from ACORN (PRNG) to ACORN (random number generator). The result of the discussion was moved. |
Do any editors here have a wp:coi? Slatersteven ( talk) 16:54, 6 April 2022 (UTC)
The result of the move request was: moved. ( non-admin closure) {{replyto| SilverLocust}} ( talk) 01:27, 8 July 2023 (UTC)
ACORN (PRNG) → ACORN (random number generator) – Disambiguators should be intelligible to the common reader, not jargon. * Pppery * it has begun... 00:04, 1 July 2023 (UTC)
Hello! I've wanted to to give this PRNG a try before, but the current example code is somewhat impenetrable. I ran it through chatgpt to get a C translation, which I then turned into a C++11 implementation. It looks like this (i have no idea how to format it on this page):
// State array of arbitrary size.
// The first element must be odd, the other elements can be randomly set.
std::array<uint64_t, 16> state {
0xE907505CB59C77D1, 0x8D6CA05F581DA875, 0x66F0C7ABEDA8D656, 0xEA0FF0093C2D3AB4,
0x48DE7C3E7FA5F645, 0xDF816A1E4941B30E, 0x28FF5C18C591C8B2, 0xD86AB519D00D93E1,
0x7D1A153C980DEA8A, 0xAFF20955CB3FFC46, 0xA63707C164CD19F4, 0x953458E388B9020C,
0xCFCA87EBA0626046, 0x1E9AF6B90B7EBF91, 0xE86BDCAAE59D8EDA, 0xD0B78E2AD9B6C63D,
};
uint32_t acorn_u32() {
// Update the current element by adding the previous element to it.
// Note: the first element is never updated.
for(int x = 1; x < state.size(); ++x) {
state[x] += state[x - 1];
}
// Return the high bits of the last element of the array.
return state.back() >> 32;
}
Does this seem fit for inclusion?
Notes:
Unlike the current example which generates 64 bits and turns it into a double precision float, this code simply generates 32 bits (should maybe be even less? see below).
Also, I'm pretty sure the float generation method used in the fortran example code (division by modulus) introduces bias and besides, it isn't strictly part of the PRNG so I left it out.
Something else that doesn't seem to be mentioned anywhere is that the lower bits are of poor quality. Returning the full 64-bit element quickly fails PractRand's tests. I wanted to make sure I didn't do anything wrong so I searched around and found these polish forum posts (used google translate to read): [1]. This person realized the same thing: casting the generated bits to a double float will discard some of the lower bits and mask the problem, but it's not exactly spelled out very clearly.
Now, the C++ example code outputs 32 bits and will actually fail PractRand pretty early as well... to avoid this, 128 bit elements could be used or the output could be smaller (24 bits seem fine but isn't a convenient size, so the next step is 16 bits). I'm not a fan of either really, but if we would like the example to not fail PractRand early I'd maybe go with 16 bit output as 128 bit integers aren't super common (I think?).
Quick aside... I think everyone already knows, but the article was clearly written by someone with vested interest, haha. Fred Underscore ( talk) 09:07, 5 July 2023 (UTC)
<syntaxhighlight lang="c++">...</syntaxhighlight>
which would give:// State array of arbitrary size.
// The first element must be odd, the other elements can be randomly set.
std::array<uint64_t, 16> state {
0xE907505CB59C77D1, 0x8D6CA05F581DA875, 0x66F0C7ABEDA8D656, 0xEA0FF0093C2D3AB4,
0x48DE7C3E7FA5F645, 0xDF816A1E4941B30E, 0x28FF5C18C591C8B2, 0xD86AB519D00D93E1,
0x7D1A153C980DEA8A, 0xAFF20955CB3FFC46, 0xA63707C164CD19F4, 0x953458E388B9020C,
0xCFCA87EBA0626046, 0x1E9AF6B90B7EBF91, 0xE86BDCAAE59D8EDA, 0xD0B78E2AD9B6C63D,
};
uint32_t acorn_u32() {
// Update the current element by adding the previous element to it.
// Note: the first element is never updated.
for(int x = 1; x < state.size(); ++x) {
statex += statex - 1];
}
// Return the high bits of the last element of the array.
return state.back() >> 32;
}
::::// State array of arbitrary size.
::::// The first element must be odd, the other elements can be randomly set.
::::std::array<uint64_t, 16> state {};
::::