双精度值在[0.0,1.0]范围内的唯一值总数是多少?

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#,这个问题是语言无关,更多的是离散数学不是编程,但它困扰我不主要是从数学的好奇感,但是从想使用一个公式,只有当它做什么它一个程序员应该从安全角度来做.

wno*_*ise 7

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位.)

  • @Chris:这个问题是伪随机数的"独立性"之一.一个意想不到的问题是,具有*n*个不同种子的*n*个不同序列将不会从每个序列产生完全独立的*n*个数字元组.您甚至可能不想使用单个序列中的相邻对.您必须在序列中使用两个彼此偏移的值.这就是为什么优秀的RNG具有"跳头"功能,因此您可以使用与序列中更远的值配对的值. (2认同)

xan*_*tos 5

作为你问题的必然结果,我会告诉你RandomC#生成器在内部使用一个"给他"数字的生成器0...Int32.MaxValue - 1.然后它将数字除以Int32.MaxValue(技术上它乘以该数字的倒数)以返回一个双精度数.所以在C#中,只Int32.MaxValue返回可能的双打(0...Int32.MaxValue - 1)