Home > OS >  Function in Python to generate random float numbers in range [a, b) - without upper bound
Function in Python to generate random float numbers in range [a, b) - without upper bound

Time:08-14

A function random.random() generates random float numbers in range [0, 1), a half-open range. On the other hand, a function uniform(a, b) generates numbers in range [a, b] or [a, b) (cannot be specified explicitly) according docs. I am looking for Python function to generate random float numbers only in range [a, b) (without upper bound).

I looked at several questions e.g. to this one but I didn't find answer.

CodePudding user response:

From the documentation, it looks like numpy.random.uniform actually does what you want:

Samples are uniformly distributed over the half-open interval [low, high) (includes low, but excludes high)

Solution:

import numpy as np

x = np.random.uniform(a, b)

CodePudding user response:

Unless your b is exceedingly close to a, it is extremely unlikely that b will ever be the exact output of your random number generator (unless the generator is itself bad), so I would recommend accepting a tiny bias and just returning any relevant value, e.g. a, if the result happens to be b. For example, assuming gen(a, b) is how you are generating values between a and b,

def closed_open_rand(a, b):
    r = gen(a, b)
    if r == b:
        return a
    return r

This will introduce a tiny bias towards the value a that you probably don't care about. If you really care about avoiding this tiny bias, you can instead give up determinism:

def closed_open_rand(a, b):
    while (r := gen(a, b)) == b:
        pass
    return r

This method avoids the tiny bias, but could theoretically be an infinite loop if your generator is bad.

If you really care about both avoiding tiny bias and maintaining determinism, then you need to look into more sophisticated methods.

CodePudding user response:

You could do something like this:

from random import choice
from numpy import arange

start = 0
stop = 1
precision = 0.00001
choice(arange(start, stop, precision))

where choice picks randomly a number from a float range. Stop is excluded since it uses a range.

CodePudding user response:

import random
def rand_float(a, b):
    return random.random() * (b-a)   a

This function should work. It utilizes the fact that random.random() returns [0, 1) and just scales it up according to the desired range, then applying an offset so that it will begin in the correct place.

Example:

print(rand_float(1, 5.3)) # could give 3.6544643 or 4.2999 but not 5.3

This doesn't take into account floating-point precision issues, but for most cases it will work.

  • Related