bli*_*sta 8 language-agnostic random floating-point discrete-mathematics
Random.NextDouble()(一个从双[0.0,1.0的范围内))有时具有大的Int64相乘(让大的Int64 = 9000000000L),并且将结果地板以获得随机的Int64值比可以从随机获得较大.Next()(范围为[0,Int32.MaxValue)的Int32).
Random r = new Random();
long big = 9000000000L;
long answer = (long) (r.NextDouble() * big);
Run Code Online (Sandbox Code Playgroud)
在我看来,在[0.0,1.0]范围内Double的唯一值的总数提供了它可能生成的唯一Int64的数量的上限.事实上,一个松散的上限,因为许多不同的双打将映射到相同的Int64.
因此,我想知道:在[0.0,1.0]范围内,double的唯一值总数是多少?
如果你可以告诉我"大"可以采取的最大值是什么,以便"回答"可以是范围[0,大]的值,以及"回答"的值的分布是否均匀,假设Random.NextDouble()是统一的.
编辑:Double(double)在这里指的是IEEE 754浮点双精度,而Int64(long)和Int32(int)分别指64位和32位有符号2的补码.
灵感来自这个问题:在java中生成10位唯一随机数
虽然我使用C#,这个问题是语言无关,更多的是离散数学不是编程,但它困扰我不主要是从数学的好奇感,但是从想使用一个公式,只有当它做什么它一个程序员应该从安全角度来做.
IEEE-754有11位指数,52位尾数.假设符号位为0(正),如果指数范围从0x001到0x3FE,则该值是0到1之间的标准浮点数.尾数用未存储的前导1解释.对于指数的这些0x3FE值中的每一个,尾数有2 ^ 52个值.此外,如果指数是0x000,则尾数被解释为没有该前导值,但好像指数是0x001,总共0x3FF = 1023指数,其中所有尾数都是有效的.这总共是1023*2 ^ 52个值.此外,负0可以计数,这是一个值.
如果从所有值均匀地生成随机双精度,则在乘法时确实会产生偏差以生成Int64.但是,任何合理的随机库都将近似于[0,1]上的均匀分布,并且在将其转换为Int64时不会产生偏差.允许生成[0,大]中的所有整数的"大"的最大值是2 ^ 53--在1/2和1之间的2 ^ 52数的分辨率是2 ^( - 53).但是,通常情况下,这些数字是通过将随机整数除以整数范围(通常为Int32)产生的,这意味着您实际上不能生成比此源更多的数字.考虑直接组合两个Int32,例如通过将一个32位移位并将它们组合成Int64.(虽然要小心 - 生成器的状态空间可能只有32位.)
作为你问题的必然结果,我会告诉你RandomC#生成器在内部使用一个"给他"数字的生成器0...Int32.MaxValue - 1.然后它将数字除以Int32.MaxValue(技术上它乘以该数字的倒数)以返回一个双精度数.所以在C#中,只Int32.MaxValue返回可能的双打(0...Int32.MaxValue - 1)