Tôi luôn nghĩ các số ngẫu nhiên sẽ nằm giữa 0 và 1, không có1
nghĩa là chúng là các số trong khoảng thời gian nửa mở [0,1). Các documention trên cppreference.com của std::generate_canonical
xác nhận điều này.
Tuy nhiên, khi tôi chạy chương trình sau:
#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;
}
Nó cho tôi đầu ra sau:
Bug!
tức là nó tạo cho tôi một sự hoàn hảo 1
, điều này gây ra vấn đề trong việc tích hợp MC của tôi. Đó là hành vi hợp lệ hoặc có một lỗi về phía tôi? Điều này cho cùng một đầu ra với G ++ 4.7.3
g++ -std=c++11 test.c && ./a.out
và kêu 3,3
clang++ -stdlib=libc++ -std=c++11 test.c && ./a.out
Nếu đây là hành vi đúng, làm thế nào tôi có thể tránh 1
?
Chỉnh sửa 1 : G ++ từ git dường như bị vấn đề tương tự. Tôi đang trên
commit baf369d7a57fb4d0d5897b02549c3517bb8800fd
Date: Mon Sep 1 08:26:51 2014 +0000
và biên dịch với ~/temp/prefix/bin/c++ -std=c++11 -Wl,-rpath,/home/cschwan/temp/prefix/lib64 test.c && ./a.out
cho cùng một đầu ra, ldd
sản lượng
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)
Chỉnh sửa 2 : Tôi đã báo cáo hành vi tại đây: https://gcc.gnu.org/ormszilla/show_orms.cgi?id=63176
Chỉnh sửa 3 : Nhóm clang dường như nhận thức được vấn đề: http://llvm.org/bugs/show_orms.cgi?id=18767
abs(random - 1.f) < numeric_limits<float>::epsilon
kiểm tra nếu kết quả gần bằng 1.0 , điều này hoàn toàn sai trong ngữ cảnh này: có những số gần với 1.0 là kết quả hợp lệ ở đây, cụ thể là, tất cả những số nhỏ hơn 1.0.
1.f == 1.f
trong mọi trường hợp (tất cả các trường hợp đều ở đó? Tôi thậm chí không thấy bất kỳ biến nào trong1.f == 1.f
đó; chỉ có một trường hợp ở đây:1.f == 1.f
và đó là bất biếntrue
). Xin đừng truyền bá huyền thoại này hơn nữa. So sánh điểm nổi luôn chính xác.