ฉันคิดเสมอว่าตัวเลขสุ่มจะอยู่ระหว่างศูนย์และหนึ่งโดยที่ไม่ใช่1
ตัวเลขจากช่วงครึ่งเปิด [0,1) documention บน cppreference.comของstd::generate_canonical
ยืนยันนี้
อย่างไรก็ตามเมื่อฉันเรียกใช้โปรแกรมต่อไปนี้:
#include <iostream>
#include <limits>
#include <random>
int main()
{
std::mt19937 rng;
std::seed_seq sequence{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
rng.seed(sequence);
rng.discard(12 * 629143 + 6);
float random = std::generate_canonical<float,
std::numeric_limits<float>::digits>(rng);
if (random == 1.0f)
{
std::cout << "Bug!\n";
}
return 0;
}
มันให้ผลลัพธ์ต่อไปนี้:
Bug!
นั่นคือมันทำให้ฉันสมบูรณ์แบบ1
ซึ่งทำให้เกิดปัญหาในการรวม MC ของฉัน เป็นพฤติกรรมที่ถูกต้องหรือมีข้อผิดพลาดในฝั่งของฉัน? สิ่งนี้ให้ผลลัพธ์เดียวกันกับ G ++ 4.7.3
g++ -std=c++11 test.c && ./a.out
และเสียงดัง 3.3
clang++ -stdlib=libc++ -std=c++11 test.c && ./a.out
หากเป็นพฤติกรรมที่ถูกต้องฉันจะหลีกเลี่ยงได้1
อย่างไร?
แก้ไข 1 : G ++ จาก git ดูเหมือนจะประสบปัญหาเดียวกัน ฉันอยู่
commit baf369d7a57fb4d0d5897b02549c3517bb8800fd
Date: Mon Sep 1 08:26:51 2014 +0000
และการรวบรวมด้วย~/temp/prefix/bin/c++ -std=c++11 -Wl,-rpath,/home/cschwan/temp/prefix/lib64 test.c && ./a.out
จะให้ผลลัพธ์เดียวกันldd
ให้ผลตอบแทน
linux-vdso.so.1 (0x00007fff39d0d000)
libstdc++.so.6 => /home/cschwan/temp/prefix/lib64/libstdc++.so.6 (0x00007f123d785000)
libm.so.6 => /lib64/libm.so.6 (0x000000317ea00000)
libgcc_s.so.1 => /home/cschwan/temp/prefix/lib64/libgcc_s.so.1 (0x00007f123d54e000)
libc.so.6 => /lib64/libc.so.6 (0x000000317e600000)
/lib64/ld-linux-x86-64.so.2 (0x000000317e200000)
แก้ไข 2 : ฉันรายงานพฤติกรรมที่นี่: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176
แก้ไข 3 : ทีมเสียงดังดูเหมือนจะตระหนักถึงปัญหา: http://llvm.org/bugs/show_bug.cgi?id=18767
abs(random - 1.f) < numeric_limits<float>::epsilon
ตรวจสอบว่าผลลัพธ์ใกล้เคียงกับ 1.0หรือไม่ซึ่งผิดโดยสิ้นเชิงในบริบทนี้: มีตัวเลขที่ใกล้เคียงกับ 1.0 ซึ่งเป็นผลลัพธ์ที่ถูกต้องที่นี่กล่าวคือทั้งหมดที่มีค่าน้อยกว่า 1.0
1.f == 1.f
ในทุกกรณี (ทุกกรณีมีอะไรบ้างฉันไม่เห็นตัวแปรใด ๆ เลย1.f == 1.f
มีเพียงกรณีเดียวที่นี่:1.f == 1.f
และนั่นก็คงเส้นคงวาtrue
) โปรดอย่าเผยแพร่ตำนานนี้ต่อไป การเปรียบเทียบจุดลอยเป็นสิ่งที่แน่นอนเสมอ