แก้ไข:ดังนั้นโดยทั่วไปสิ่งที่ฉันพยายามที่จะเขียนเป็นกัญชา 1 double
บิตสำหรับ
ฉันต้องการที่จะแมปdouble
ไปtrue
หรือfalse
มีโอกาสที่ 50/50 สำหรับที่ฉันเขียนโค้ดที่เลือกตัวเลขสุ่ม(เช่นเป็นตัวอย่างฉันต้องการใช้กับข้อมูลที่มี regularities และยังได้ผลลัพธ์ 50/50)ตรวจสอบบิตสุดท้ายและส่วนเพิ่มy
หากเป็น 1 หรือn
ถ้าเป็น 0
แต่รหัสนี้อย่างต่อเนื่องส่งผลให้ใน 25% y
และ n
75% ทำไมมันไม่ 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
ไหม? ก็ใช่ และรับบิตสุดท้ายเป็นแฮชของ a double
คือสิ่งที่เกิดขึ้นเมื่อคุณทำตามวิธีการนี้ไปจนจบด้วยโมดูโลที่เป็นไปได้น้อยที่สุด
(lastbit & 3) == 0
จะทำงานแม้ว่าแปลกตามที่เป็นอยู่