为什么这个随机值的分布是25/75而不是50/50?

问题:

 编辑:所以基本上我正在写的是double的1位哈希值
我想以50/50的机会将double映射到truefalse。为此,我写了一些代码选择一些随机数(just as an example, I want to use this on data with regularities and still get a 50/50 result),检查它们的最后一位,如果为1,则增加y,如果为0,则检查n
不过,此代码不断导致25%y和75%n。为什么不是50/50?为什么这样一个奇怪的但是直截了当的(1/3)分布?

public class DoubleToBoolean {
@Test
public void test() {

int y = 0;
int n = 0;
Random r = new Random();
for (int i = 0; i < 1000000; i++) { double randomValue = r.nextDouble(); long lastBit = Double.doubleToLongBits(randomValue) & 1; if (lastBit == 1) { y++; } else { n++; } } System.out.println(y + " " + n); } } [/code] 示例输出: [code lang="python"] 250167 749833 [/code]

回答:

因为nextDouble这样工作:(source

public double nextDouble()
{
return (((long) next(26) << 27) + next(27)) / (double) (1L << 53); } [/code]  next(x)使x随机位。
现在为什么这么重要?因为第一部分(除法之前)产生的数字的大约一半小于1L << 52,因此它们的有效数并不完全填充它可以填充的53位,意味着有效数的最低有效位始终为零对于那些。
由于这次收到的关注,这里有一些额外的解释,Java(和许多其他语言)中的double真的是什么样的,以及为什么这个问题是重要的。
基本上,double看起来像这样:(source
 double layout
这个图片中不可见的一个非常重要的细节是数字“归一化”1,使得53位分数以1开始(通过选择指数为这样),然后省略1。这就是为什么图片显示了52位的分数(有效位数),但有效的是53位。
归一化意味着如果在nextDouble的代码中设置了第53位,则该位是隐含的前导1,它将消失,而其他52位被字面复制到生成的double的有效位置。如果该位未设置,则剩下的位必须向左移动直到它被置位。
平均而言,生成的数字的一半落在有效位数为not全部向左移位的情况(约有一半为0作为其最低有效位)的情况下,另一半移位至少1(或者是只是完全零),所以它们的最低有效位始终为0。
1:不总是清楚的,它不能为零而没有最高1,这些数字称为反常数或次正规数,见wikipedia:denormal number

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Why does this random value have a 25/75 distribution instead of 50/50?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

+ 77 = 81