Sunting: Jadi pada dasarnya yang ingin saya tulis adalah hash 1 bit double
.
Saya ingin memetakan double
ke true
atau false
dengan peluang 50/50. Untuk itu saya menulis kode yang mengambil beberapa angka acak (seperti contoh, saya ingin menggunakan ini pada data dengan keteraturan dan masih mendapatkan hasil 50/50) , memeriksa bit terakhir mereka dan kenaikan y
jika itu adalah 1, atau n
jika itu adalah 0.
Namun, kode ini secara konstan menghasilkan 25% y
dan 75% n
. Mengapa bukan 50/50? Dan mengapa distribusi yang aneh, tetapi langsung (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);
}
}
Contoh output:
250167 749833
doubleValue % 1 > 0.5
, tapi itu akan terlalu kasar karena dapat memperkenalkan keteraturan yang terlihat dalam beberapa kasus (semua nilai berada dalam kisaran panjang 1). Jika itu terlalu berbutir kasar, maka haruskah kita mencoba rentang yang lebih kecil, seperti doubleValue % 1e-10 > 0.5e-10
? Baiklah. Dan mengambil bit terakhir sebagai hash dari double
apa yang terjadi ketika Anda mengikuti pendekatan ini sampai akhir, dengan modulo sesedikit mungkin.
(lastbit & 3) == 0
akan bekerja meskipun aneh.