मैंने हमेशा सोचा था कि यादृच्छिक संख्या शून्य और एक के बीच होगी, बिना1
, यानी वे आधे खुले अंतराल [0,1) से संख्या हैं। इस बात की पुष्टि 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
, जो मेरे एमसी एकीकरण में समस्याएं पैदा करता है। क्या वह वैध व्यवहार है या मेरी तरफ से कोई त्रुटि है? यह 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)
संपादन २ : मैंने यहाँ व्यवहार की सूचना दी: 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
)। कृपया इस मिथक को और न फैलाएं। फ्लोटिंग पॉइंट की तुलना हमेशा सटीक होती है।