Modifica: Quindi sostanzialmente quello che sto cercando di scrivere è un hash a 1 bit per double.
Voglio mappare un doublea trueo falsecon una probabilità 50/50. Per questo ho scritto un codice che seleziona alcuni numeri casuali (solo come esempio, voglio usarlo su dati con regolarità e ottenere comunque un risultato 50/50) , controlla il loro ultimo bit e incrementa yse è 1, o nse lo è 0.
Tuttavia, questo codice risulta costantemente nel 25% ye nel 75% n. Perché non è 50/50? E perché una distribuzione così strana, ma diretta (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);
}
}
Esempio di output:
250167 749833
doubleValue % 1 > 0.5, ma sarebbe troppo grossolano poiché in alcuni casi può introdurre regolarità visibili (tutti i valori sono compresi nell'intervallo di lunghezza 1). Se è troppo a grana grossa, allora dovremmo probabilmente provare intervalli più piccoli, come doubleValue % 1e-10 > 0.5e-10? Beh si. E prendere solo l'ultimo bit come hash di a doubleè ciò che accade quando segui questo approccio fino alla fine, con il modulo il meno possibile.
(lastbit & 3) == 0funzionerebbe comunque, per quanto sia strano.
