Movatterモバイル変換


[0]ホーム

URL:


[Python-ideas] New function to add into the "random" module

Franklin? Leeleewangzhong+python at gmail.com
Thu Feb 2 09:21:42 EST 2017


On Thu, Feb 2, 2017 at 7:01 AM, <himchanterry at gmail.com> wrote:> from random import *>>>> def randfloat(x , y , maxfloatpt=None):>>     if x > y:>>         x , y = y , x>>     lenx = len(str(x))>>     leny = len(str(y))>>     intx = int(x)>>     inty = int(y)>>     bigger = max(lenx,leny)>>     if maxfloatpt == None:>>         if bigger == lenx:>>             intxlen = len(str(intx))>>             maxfloatpt = len(str(x)[intxlen:])>>         elif bigger == leny:>>             intylen = len(str(inty))>>             maxfloatpt = len(str(y)[intylen:])>>         else:>>             pass>>    else:>>         pass>>     num = randint(intx , inty)>>     num = str(num)>>     num = '%s.' % num>>     for i in range(0 , maxfloatpt):>>         flnum = randint(0 , 9)>>         str(flnum)>>         num = '%s%s' % (num , flnum)>>     return float(num)>>>> P.S.: If the indent has anything wrong, just correct me, thx!>>>> P.P.S.: The function is tested, it’s working 😊>It looks like this is generating a random float one digit at a time.Instead, consider the following:Say you have a function which generates a number between 0 and n. You wantto generate a number between floats x and y, as fairly as you can. Sostretch the range 0...n onto the range x...y, linearly. That means 0 goesto x, n goes to y, things close to 0 go to things close to x, etc.If x is 0, then it's simple:    def stretch(num):        return num / n * yWe just need to make x = 0 temporarily, shifting y down as well:    def stretch(num):        return (num / n * (y - x)) + xReally, we care about the _length_ of the interval [x,y], relative to thelength of [0,n].Since we want to reach as many numbers as possible in [x,y], we just need nto be really big. The limit of n depends on how randint is implemented. I'mnot sure whether Python uses extra randoms in the case of long ints, butlet's say that 2^15 is both big enough for us and small enough for Python'srandints to be pretty random.    import random    def randfloat(x, y):        r = random.randint(0, 2**15) #our random int        length = y - x #length of the interval        f = (r / 2**15 * length) + x        return f(Python 2 will do truncating division up there, so you'd need to make it dofloating point division with a __future__ import or a cast.)To be responsible, we should probably up the limit to around 2^54 (which isthe limit of precision for the 64-bit floats used by Python), and we'd needto learn about how random randint can be with large numbers, then generatelarger random numbers using smaller ones.To be really responsible, we would not assume that floats are 64-bit.(Fortunately, we don't have to be responsible, because Daniel pointed outthat this function exists in Python's random.)The idea of linearly mapping one range to another is useful, so pleaseremember it. In fact, the stretch works even if x is bigger than y.-------------- next part --------------An HTML attachment was scrubbed...URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170202/2efc8bc0/attachment.html>


More information about the Python-ideasmailing list

[8]ページ先頭

©2009-2026 Movatter.jp