Skip to content

Commit 3ee4bff

Browse files
JKaniarzslouken
authored andcommitted
Upgraded constants after statistical testing.
1 parent 83d21e2 commit 3ee4bff

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

src/stdlib/SDL_random.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,29 @@ float SDL_rand_float(void)
5454
return (SDL_rand() >> (32-24)) * 0x1p-24f;
5555
}
5656

57-
/* A fast psuedo-random number generator.
58-
* Not suitable for cryptography or gambling
59-
*/
6057
Uint32 SDL_rand_r(Uint64 *state)
6158
{
6259
if (!state) {
6360
return 0;
6461
}
6562

66-
// Multiplier from Table 6 of
67-
// Steele GL, Vigna S. Computationally easy, spectrally good multipliers
68-
// for congruential pseudorandom number generators.
69-
// Softw Pract Exper. 2022;52(2):443-458. doi: 10.1002/spe.3030
63+
// The C and A parameters of this LCG have been chosen based on hundreds
64+
// of core-hours of testing with PractRand and TestU01's Crush.
65+
// Using a 32-bit A improves performance on 32-bit architectures.
66+
// C can be any odd number, but < 256 generates smaller code on ARM32
67+
// These values perform as well as a full 64-bit implementation against
68+
// Crush and PractRand. Plus, their worst-case performance is better
69+
// than common 64-bit constants when tested against PractRand using seeds
70+
// with only a single bit set.
7071

71-
// 32-bit 'a' improves performance on 32-bit architectures
72-
// 'c' can be any odd number, but < 256 generates smaller code on some arch
73-
*state = *state * 0xf9b25d65ul + 0xFD;
72+
// We tested all 32-bit and 33-bit A with all C < 256 from a v2 of:
73+
// Steele GL, Vigna S. Computationally easy, spectrally good multipliers
74+
// for congruential pseudorandom number generators.
75+
// Softw Pract Exper. 2022;52(2):443-458. doi: 10.1002/spe.3030
76+
// https://arxiv.org/abs/2001.05304v2
7477

75-
// Only return top 32 bits because they have a longer period
76-
return (Uint32)(*state >> 32);
78+
*state = *state * 0xff1cd035ul + 0x05;
79+
80+
// Only return top 32 bits because they have a longer period
81+
return (Uint32)(*state >> 32);
7782
}

0 commit comments

Comments
 (0)