Edit: Donc, fondamentalement, ce que j'essaie d'écrire est un hachage de 1 bit double
.
Je veux mapper un double
à true
ou false
avec une chance de 50/50. Pour cela, j'ai écrit du code qui sélectionne des nombres aléatoires (juste à titre d'exemple, je veux l'utiliser sur des données avec des régularités et obtenir toujours un résultat 50/50) , vérifie leur dernier bit et incrémente y
s'il est 1, ou n
s'il est 0.
Cependant, ce code aboutit constamment à 25% y
et 75% n
. Pourquoi n'est-ce pas 50/50? Et pourquoi une distribution aussi étrange, mais simple (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);
}
}
Exemple de sortie:
250167 749833
doubleValue % 1 > 0.5
, mais ce serait trop grossier car cela peut introduire des régularités visibles dans certains cas (toutes les valeurs sont dans la plage de longueur 1). Si c'est trop gros, devrions-nous probablement essayer des gammes plus petites, comme doubleValue % 1e-10 > 0.5e-10
? Hé bien oui. Et prendre juste le dernier bit comme hachage de a, double
c'est ce qui se passe lorsque vous suivez cette approche jusqu'à la fin, avec le moins de modulo possible.
(lastbit & 3) == 0
fonctionnerait cependant, aussi étrange que cela puisse paraître.