Does this really generate a random insertion point number? (Python)

For an introduction to the Python course, I am considering creating a random floating point number in Python, and I saw the standard recommended code

import random lower = 5 upper = 10 range_width = upper - lower x = random.random() * range_width + lower 

for a random floating point from 5 to but not including 10.

It seems to me that the same effect can be achieved:

 import random x = random.randrange(5, 10) + random.random() 

Since this will give an integer of 5, 6, 7, 8 or 9, and then attach a decimal number to it.

The question that I have is that this second code still gives a completely uniform probability distribution, or does it not preserve the complete randomness of the first version?

+5
source share
3 answers

According to the documentation , then yes random() indeed a uniform distribution.

random() , which evenly generates a random float in the half-open range [0.0, 1.0]. Python uses Mersenne Twister as its primary generator.

So, both code examples should be accurate. To shorten the code, you can also:

 random.uniform(5, 10) 

Note that uniform(a, b) just a + (b - a) * random() , just like your first example.

The second example depends on the version of Python you are using. Prior to 3.2 randrange() , a somewhat uneven distribution may occur.

+6
source

There is a difference. Your second method is theoretically superior, although in practice this only matters for large ranges. Indeed, both methods will give you a uniform distribution. But only the second method can return all values ​​in a range that are represented as a floating point number.

Since your range is so small, there is no noticeable difference. But still there is a difference that you can see when considering a wider range. If you accept a random real number between 0 and 1, you get a floating point representation with a given number of bits. Now suppose your range is, say, of the order of 2**32 . By multiplying the original random number by this range, you lose 32 bits of precision as a result. In other words, there will be gaps between the values ​​that this method can return. Gaps still exist when you multiply by 4: you have lost the two least significant bits of the original random number.

+2
source

The two methods can give different results, but you will notice the difference in fairly extreme situations (with very wide ranges). For example, if you generate random numbers between 0 and 2/sys.float_info.epsilon ( 9007199254740992.0 or just over 9 quintillion), you will notice that the version using multiplication will never give you any floats with fractional values. If you increase the maximum border to 4/sys.float_info.epsilon , you will not get any odd integers, only even ones. This is because using the 64-bit Python floating-point type does not have sufficient precision to represent all integers at the upper end of this range and tries to maintain uniform distribution (therefore, it omits small odd integers and fractional values, even if these can be represented in parts of the range).

The second version of the calculation will provide additional accuracy for the generated smaller random numbers. For example, if you generate numbers between 0 and 2/sys.float_info.epsilon , and the randrange call returns 0 , you can use the full precision of the random call to add the fractional part to the number. On the other hand, if randrange returns the largest number in the range ( 2/sys.float_info.epsilon - 1 ), very little fraction precision will be used (the number will be rounded to the nearest integer without the remainder).

Adding a fractional value will also not help you cope with ranges that are too large for every integer to be represented. If randrange returns only even numbers, adding a fraction usually will not result in odd numbers (this may be in some parts of the range, but not for others, and the distribution can be very uneven). Even for ranges where all integers can be represented, the likelihood of a particular floating point number will not be completely uniform, since smaller digits can be more accurately represented. Larger but inaccurate numbers will be more common than smaller but more accurately presented ones.

+1
source

Source: https://habr.com/ru/post/1265627/


All Articles