Edit: Então, basicamente, o que estou tentando escrever é um hash de 1 bit double
.
Quero mapear uma double
para true
ou false
com uma chance de 50/50. Para isso, escrevi um código que seleciona alguns números aleatórios (como exemplo, quero usar isso em dados com regularidades e ainda obter um resultado 50/50) , y
verifico seu último bit e incrementa se for 1 ou n
se for 0
No entanto, esse código resulta constantemente em 25% y
e 75% n
. Por que não é 50/50? E por que uma distribuição tão estranha, mas direta (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);
}
}
Exemplo de saída:
250167 749833
doubleValue % 1 > 0.5
, mas isso seria muito grosseiro, pois pode introduzir regularidades visíveis em alguns casos (todos os valores estão dentro do intervalo 1). Se isso é muito granular, provavelmente deveríamos tentar intervalos menores, como doubleValue % 1e-10 > 0.5e-10
? Bem, sim. E tomar apenas o último pedaço como um hash de a double
é o que acontece quando você segue essa abordagem até o fim, com o módulo menos possível.
(lastbit & 3) == 0
iria funcionar, por mais estranho que seja.