Generate random number between 0.1 and 1.0. Python

后端 未结 10 1847
南方客
南方客 2020-12-29 05:23

I\'m trying to generate a random number between 0.1 and 1.0. We can\'t use rand.randint because it returns integers. We have also tried random.uniform(0.1

10条回答
  •  离开以前
    2020-12-29 05:42

    Random.uniform() is just:

    def uniform(self, a, b):
        "Get a random number in the range [a, b) or [a, b] depending on rounding."
        return a + (b-a) * self.random()
    

    where self.random() returns a random number in the range [0.0, 1.0).

    Python (as well as many other languages) uses floating point to represent real numbers. How 0.1 is represented is described in detail in the docs:

    from __future__ import division
    
    BPF = 53 # assume IEEE 754 double-precision binary floating-point format
    N = BPF + 3
    assert 0.1 == 7205759403792794 / 2 ** N
    

    It allows to find a random number in [0.1, 1] (inclusive) using randint() without losing precision:

    n, m = 7205759403792794, 2 ** N
    f = randint(n, m) / m
    

    randint(n, m) returns a random integer in [n, m] (inclusive) therefore the above method can potentially return all floating points numbers in [0.1, 1].

    An alternative is to find the smallest x such that x > 1 and use:

    f = uniform(.1, x)
    while f > 1:
        f = uniform(.1, x)
    

    x should be the smallest value to avoid losing precision and to reduce number of calls to uniform() e.g.:

    import sys
    # from itertools import count
    
    # decimal.Decimal(1).next_plus() analog
    # x = next(x for i in count(1) for x in [(2**BPF + i) / 2**BPF] if x > 1)
    x = 1 + sys.float_info.epsilon
    

    Both solutions preserve uniformness of the random distribution (no skew).

提交回复
热议问题