Distribution of final digits of random numbers in Python

That’s not “the last digit” of the number. That’s the last digit of the string str gave you when passed the number.

When you call str on a float, Python gives you enough digits that calling float on the string will give you the original float. For this purpose, a trailing 1 or 9 is less likely to be necessary than other digits, because a trailing 1 or 9 means the number is very close to the value you’d get by rounding off that digit. There’s a good chance no other floats are closer, and if so, that digit can be discarded without sacrificing float(str(original_float)) behavior.

If str gave you enough digits to exactly represent the argument, the last digit would almost always be 5, except when random.random() returns 0.0, in which case the last digit would be 0. (Floats can only represent dyadic rationals, and the last nonzero decimal digit of a non-integer dyadic rational is always 5.) The outputs would also be extremely long, looking like

>>> import decimal, random
>>> print(decimal.Decimal(random.random()))
0.29711195452007921335990658917580731213092803955078125

which is one of the reasons str doesn’t do that.

If str gave you exactly 17 significant digits (enough to distinguish all float values from each other, but sometimes more digits than necessary), then the effect you’re seeing would disappear. There would be a nearly uniform distribution of trailing digits (including 0).

(Also, you forgot that str sometimes returns a string in scientific notation, but that’s a minor effect, because there’s a low probability of getting a float where that would happen out of random.random().)

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)