is it possible to find random floats in range [a,b] in python?

后端 未结 5 2091
旧巷少年郎
旧巷少年郎 2021-01-06 17:07

I\'m trying to generate in python random floats in the range of [0.8,0.9] , but unfortanetly all the tools i found could only generate randoms in the range of [a,b) for floa

相关标签:
5条回答
  • 2021-01-06 17:20

    The probability of generating exactly an endpoint value should be negligible. What bad consequences do you worry about if you just use Random.uniform(0.8,0.9)? (And are you also worried about the fact that the double-precision floats you get when you say "0.8" and "0.9" aren't in fact exactly 8/10 and 9/10?)

    It's possible that you have very unusual requirements; but for, say, 99.9% of applications I think the answer is: just use Random.uniform(a,b) and don't worry about it.

    0 讨论(0)
  • 2021-01-06 17:23

    The docs say that uniform(a, b) generates a number in [a, b]1, but this appears to be a documentation error, since the source shows it to rely on random(), which, according to the docs, returns [0.0, 1.0)2.

    If you must have [a, b], then you can try generating this range from an integer:

    random.inclusive_uniform = lambda a, b:
        random.randint(0, 0xFFFFFFFF) / float(0xFFFFFFFF) * (b - a) + a
    

    I say "try" generating this range, because when the bounds cannot be precisely represented (neither 0.8 and 0.9 can be precisely represented in IEEE-754), then the range is actually [a', b'], where a' and b' are whatever a and b get rounded to. Note that this might even be greater than the range [a, b], so beware!

    1 Specifically, it says that return value N is limited to a <= N <= b.

    2 In a comment in the source, however, is an assertion that it can never actually be 0.0, so I guess range is actually (0.0, 1.0).

    0 讨论(0)
  • 2021-01-06 17:25

    The difference between [0.8, 0.9] and [0.8,0.9) is vanishingly small. Given the limitations of binary floating-point, I don't think there even is a difference, since 0.9 can't be precisely represented anyway. Use [0.8,0.9).

    0 讨论(0)
  • 2021-01-06 17:27

    If it really matters, then you can do this:

    def uniform_closed(a, b):
         while True:
             r = random.uniform(a, b + (b - a) * 0.01)
             if r <= b: return r
    
    0 讨论(0)
  • 2021-01-06 17:41

    Quoting the random.uniform() docstring:

    Get a random number in the range [a, b) or [a, b] depending on rounding.

    So you don't even know if the endpoint is included or not. But you should not care either -- there are 900719925474100 floating point numbers in the range [0.8, 0.9]. It will take a lifetime until a single one of them occurs anyway, so there is no practical difference to including the endpoint or not, even if the endpoint can be represented exactly as a floating point number.

    0 讨论(0)
提交回复
热议问题