Math.random返回0的几率是多少?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Math.random返回0的几率是多少?相关的知识,希望对你有一定的参考价值。

就像this question的提问者一样,我想知道为什么Math.ceil(Math.random() * 10)不比Math.floor(Math.random() * 10) + 1更受欢迎,并且发现这是因为Math.random有一个很小(但相关)的机会完全返回0。但是多么微小?

进一步的研究告诉我,this random number is accurate to 16 decimal places... well, sort of.这是我对此感到好奇的“那种”。

我知道浮点数与小数的工作方式不同。尽管如此,我还是很努力。如果这个数字是一个严格的十进制值,我相信机会将是十分之一的台球(或美国系统中的十万亿) - 1:1016。

这是正确的,还是我弄乱了,还是浮点数有所作为?

答案

javascript是ECMAScript的一种方言。 ECMAScript-262 standard没有准确地指定Math.random。在第20.2.2.7节中,它说:

20.2.2.27 Math.random()

使用依赖于实现的算法或策略,返回具有正号,大于或等于0但小于1的Number值,随机或伪随机选择,在该范围内具有近似均匀的分布。此函数不带参数。为不同领域创建的每个Math.random函数必须从连续调用中生成不同的值序列。

在没有完整的规范的情况下,没有关于Math.random返回零的概率的明确陈述。每个ECMAScript实现可以选择不同的算法,并且不需要提供真正均匀的分布。

ECMAScript为其Number类型使用IEEE-754基本64位二进制浮点格式。在这种格式中,数字的有效数(分数部分)具有53位。每个浮点数的形式为s•f•2e,其中s(用于符号)为+1或-1,f(对于分数)是有效数,并且是[0,253]中的整数,e(对于exponent)是[-1074,971]中的整数。如果设置了高位f,则认为该数是标准化的(因此f在[252,253]中)。由于在这个答案中负数不是一个问题,所以对于这个答案的其余部分,我们可以隐式+1。

在[0,1]中分配随机数的一个问题是可表示的值不是均匀间隔的。在[½,1]中有252个可表示的值 - 所有在[252,253]和e = -53中具有f的值。在[¼,½)中有相同数量的值 - 在[252,253]和e = -54中有f的那些值。由于在该间隔中存在相同数量的数字但间隔是一半长,因此数字间隔更紧密。类似地,在[⅛,¼)中,间距再次减半。这一直持续到指数达到-1074,此时正常数字以f = 252结束。小于该数字的数字被认为是次正规(或零),f在[0,252]和e = -1074,它们间隔均匀。

关于如何分配Math.random的数字的一个选择是在[0,253]中仅对f使用均匀间隔的数字f•2-53。这使用[½,1)中的所有可表示值,但仅使用[¼,½]中的一半值,[⅛,¼]中的值的四分之一,依此类推。这很简单,避免了分发中的一些奇怪之处。如果正确实施,则产生概率零是253中的一个。

另一种选择是使用[0,1]中的所有可表示的值,每个值的概率与从它到下一个更高的可表示值的距离成比例。因此,[½,1)中的每个可表示的数字将以概率1/253选择,[¼,½]中的每个可表示的数字将以概率1/254选择,每个可表示的数字在[⅛,¼)中将被选择概率为1/255,依此类推。这种分布近似于实数上的均匀分布,并且提供了更精细的精度,其中浮点格式更精细。如果正确实现,则在21074中产生概率零。

另一种选择是使用[0,1]中的所有可表示的值,每个值的概率与段的长度成比例,其中可表示的值是段中所有实数的最接近的可表示值。我将省略对此分布的一些细节的讨论,除非说它通过选择具有均匀分布的实数来模拟结果,然后使用舍入到最近关系到偶数规则将其四舍五入到可表示的值。如果正确实现,则在21075中产生的概率为零。(这种分布的一个问题是在[0,1]中实数上的均匀分布有时会产生一个接近于1的数,使得舍入产生1。要求允许Math.random返回1或者以某种方式捏造分布,可能通过返回下一个较低的可表示值而不是1)。

我将注意到ECMAScript规范是足够宽松的,人们可能断言Math.random可以为每个可表示的值以相等的概率分配数字,忽略它们之间的间隔。这根本不会模仿真实数字的统一分布,我希望很少有人愿意这样做。但是,如果实现,则返回概率零是1021•252中的一个,因为有252个归一化数字,指数从-53到-1074(e20的1020个值),以及252个次正数或零数。

以上是关于Math.random返回0的几率是多少?的主要内容,如果未能解决你的问题,请参考以下文章

随机数生成之Math.Random()方法

java程序中Math.random();的取值范围是多少?(是0到1double型吗?)

Math.random() 的精度

关于Java里产生1-6随机数的方法

Math.random()问题

java随机数Math.random()