Editar: Entonces, básicamente, lo que estoy tratando de escribir es un hash de 1 bit double.
Quiero mapear un doubleto trueo falsecon una probabilidad de 50/50. Para eso escribí un código que selecciona algunos números aleatorios (solo como ejemplo, quiero usar esto en datos con regularidades y aún así obtener un resultado 50/50) , verifica su último bit e incrementos ysi es 1, o nsi es 0.
Sin embargo, este código constantemente produce 25% yy 75% n. ¿Por qué no es 50/50? ¿Y por qué una distribución tan extraña pero directa (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);
}
}
Salida de ejemplo:
250167 749833
doubleValue % 1 > 0.5, pero eso sería demasiado grano ya que puede introducir regularidades visibles en algunos casos (todos los valores están dentro del rango de longitud 1). Si eso es demasiado de grano grueso, ¿deberíamos intentar rangos más pequeños, como doubleValue % 1e-10 > 0.5e-10? Bueno, sí. Y tomar solo el último bit como hash de a doublees lo que sucede cuando sigues este enfoque hasta el final, con el mínimo módulo posible.
(lastbit & 3) == 0funcionaría sin embargo, por extraño que sea.
