Редагувати: В основному те, що я намагаюся написати, це 1-бітний хеш double
.
Я хочу скласти карту double
до true
або false
з можливістю 50/50. Для цього я написав код, який підбирає деякі випадкові числа (як приклад, я хочу використовувати це на даних із закономірностями і все-таки отримувати результат 50/50) , перевіряє їх останній біт і приріст, y
якщо він 1, або n
якщо це 0.
Однак цей код постійно призводить до 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);
}
}
Приклад виводу:
250167 749833
doubleValue % 1 > 0.5
, але це було б занадто грубозернистим, оскільки воно може ввести видимі закономірності в деяких випадках (усі значення знаходяться в межах 1 довжини). Якщо це занадто грубозерниста, то, мабуть, ми повинні спробувати менші діапазони, як doubleValue % 1e-10 > 0.5e-10
? Ну так. І якщо взяти останній шматочок як хеш а, double
це те, що відбувається, коли дотримуватися цього підходу до кінця, з найменшим можливим модулем.
(lastbit & 3) == 0
Працює хоч як не дивно.