Using seed breaks .integer
See original GitHub issueI’m using 1.0.18.
Reproduce with this: new Chance(Math.random()).integer({min:1,max:3})
This returns a value of 2
100% of the time.
Issue Analytics
- State:
- Created 4 years ago
- Comments:6 (5 by maintainers)
Top Results From Across the Web
random.seed(): What does it do? - Stack Overflow
Pseudo-random number generators work by performing some operation on a value. Generally this value is the previous number generated by the generator.
Read more >Numpy Random Seed, Explained - Sharp Sight
In this tutorial, I'll explain how to use the NumPy random seed function, which is also called np.random.seed or numpy.random.seed.
Read more >Randomizing should be easy, right? oh, well, maybe not..
srand() takes an integer, so something like $seed = rand(); srand($seed) would always lead to seeding the prng with 0, not good at...
Read more >Random number generator seed mistakes
Stories of projects that have made mistakes seeding a random number generator and better ways to do it.
Read more >Challenge 22: Crack an MT19937 seed - GitLab
Make sure your MT19937 accepts an integer seed value. Test it (verify that you're getting the same sequence of outputs given a seed)....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hey @gerardolima, here’s my feedback as to why
Math.random()
as a seed isn’t optimal, but also technically supported.TL;DR: The built-in MersenneTwister takes the seed, unsigned right shifted, and goes from there. Anything between 0 and 1 becomes 0.
The built-in MersenneTwister uses the seed to populate an array of pseudorandom numbers. It’s expecting a seed between 0 and 10_000_000_000_000
Let’s pick a number from 1 to 10, using seeds 0 to 4.
mt.random()
to choose an int[0, 1, 1812433255, ...]
[1, 1812433254, ...]
[2, 3624866507, ...]
[3, 1142332464, ...]
[4, 2954765717, ...]
Initializing the MT with such close integers and only providing a field of 1-10 for
integer()
to choose (once), returns 6,5,5,10.Narrow the field to
{min:1,max:3}
is like shrinking the dart board down to only 3 options.mt.random()
to choose an int[0, 1, 1812433255, ...]
[1, 1812433254, ...]
[2, 3624866507, ...]
[3, 1142332464, ...]
[4, 2954765717, ...]
Let’s see what happens if you pass a seed between 0 and 1, essentially populating the array with zero as the first entry and always returning the same pseudorandom value.
mt.random()
to choose an int[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[0, 1, 1812433255, ...]
[1, 1812433254, ...]
The same would apply to
{min:1,max:3}
and always return 2.Could the MersenneTwister be improved to support real numbers between 0 and 1 instead of ints?
Sure, but any change to the twister is a breaking change for all those expecting patterns from their fixed seeds.
Could the constructor validate and reject real numbers? Also a breaking change for those passing a real number with a larger field, such as:
new Chance(Math.random()*10_000_000_000_000);
String seeds? If a String is passed, it’s converted into an integer using each letter of the string. 😐
Recommendation?
Take advantage of the full 32 bits for a seed and stay away from 0 -> 1 and the other limit too:
hey again, @somejeff, I understand your explanation and I agree that keeping a stable interface is precious for any library.
My comment was about improving the ergonomics of the API by avoiding what looks to be a rather silly, but also one easy mistake to make. As a suggestion, Chance could trigger an error when
seed % 1 !== 0
or maybe being even more explicit, when0 < seed < 1
, which is the range ofMath.random()
. If throwing an error should sound too much, maybe log a warning on console?That said, I understand that this might break the behaviour in some cases – and maybe unfold some unintended usage of
Chance(Math.random())
– so it’s a balance and it’s obviously your call. Thank you for your good work!