Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe to seed Python RNG using float?

Can floating point values be passed as an argument to random.seed()? Does this introduce unforeseen issues?

In other words. Is....

random.seed(0.99999999)
<use a few thousand random numbers>
random.seed(1)
<use a few thousand random numbers>

.... functionally equivalent to....

random.seed(0)
<use a few thousand random numbers>
random.seed(1)
<use a few thousand random numbers>

Quick testing suggests that both sets of code run just fine and on a superficial level the outputs appear to be independent and deterministic.

I'm interested to know if this method of seeding is completely safe to use in cases where independence between seeded sets is important. Obtaining deterministic results is also important. I've checked some of the documentation: Python 2.7 documentation and Python 3.8 documentation and done some googling and only found references to integers being used as a seed (or other data types which are converted to integers). I couldn't see any reference to floats and this makes me wonder if they are "safe" in the sense that they work in a predictable way with no nasty surprises.

I'm currently working with Python 2.7 but am interested in the answer for more modern versions too.

like image 896
P. Hopkinson Avatar asked Jul 05 '26 07:07

P. Hopkinson


2 Answers

Using a float as a seed is intended functionality:

supported seed types are: None, int, float, str, bytes, and bytearray.

see: https://github.com/python/cpython/blob/master/Lib/random.py#L156

Getting a float of exactly the same value each time is critical for getting the same seed, but this is not too difficult. The most reliable way to always get the same float value is to not do any computation on it, or accept any user input. If you want to ensure complete control, you can use struct.unpack to generate a float from raw binary data.

like image 73
Aaron Avatar answered Jul 11 '26 00:07

Aaron


Yes, it is safe to use a float seed

According to the documentation, random.seed(a) uses a directly if it is an int or long, otherwise (if a is not None) it uses hash(a). Given that python requires that hash(x) == hash(y) if x == y, this means that the same sequence of pseudo-random numbers will be generated for equal float seeds (with the standard caveats about strict comparisons of floating-point numbers).

The python 3 documentation is less clear about how it handles inputs of types other than int, str, bytes, and bytearray, but the behavior itself is the same as python 2 for python 3.8 and earlier. As was mentioned in Aaron's answer, seeding based on hashing is deprecated in 3.9, but float continues to be a supported seed type.

like image 43
manveti Avatar answered Jul 10 '26 23:07

manveti



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!