Boost C++ Libraries: Ticket #7951: ranlux24_base(0) should be equal to ranlux24_base() https://svn.boost.org/trac10/ticket/7951 <p> After fixing a bug in VC11's &lt;random&gt; (see <a class="changeset" href="https://svn.boost.org/trac10/changeset/1" title="Import core sources for SVNmanger 0.38 ">[1]</a>), I compared VC's fixed output to Boost 1.52.0's output and I believe I found a bug in Boost. Here's a self-contained test case: </p> <pre class="wiki">C:\Temp&gt;type meow.cpp #include &lt;ios&gt; #include &lt;iostream&gt; #ifdef USE_BOOST #include &lt;boost/random.hpp&gt; using std::boolalpha; using std::cout; using std::endl; using boost::random::minstd_rand0; using boost::random::mt19937; using boost::random::ranlux24_base; #else #include &lt;random&gt; using namespace std; #endif template &lt;typename Engine&gt; typename Engine::result_type run_10k(Engine engine) { for (int i = 0; i &lt; 9999; ++i) { engine(); } return engine(); } int main() { cout &lt;&lt; boolalpha; #ifdef USE_BOOST cout &lt;&lt; "Using boost." &lt;&lt; endl; #else cout &lt;&lt; "Using std." &lt;&lt; endl; #endif cout &lt;&lt; "N3485 26.5.5 [rand.predef]/1 satisfied: " &lt;&lt; (run_10k( minstd_rand0()) == 1043618065) &lt;&lt; endl; cout &lt;&lt; "N3485 26.5.5 [rand.predef]/3 satisfied: " &lt;&lt; (run_10k( mt19937()) == 4123659995) &lt;&lt; endl; cout &lt;&lt; "N3485 26.5.5 [rand.predef]/5 satisfied: " &lt;&lt; (run_10k(ranlux24_base()) == 7937952 ) &lt;&lt; endl; cout &lt;&lt; "I believe minstd_rand0(0) == minstd_rand0() should be true: " &lt;&lt; (minstd_rand0(0) == minstd_rand0()) &lt;&lt; endl; cout &lt;&lt; "I believe mt19937(0) == mt19937() should be false: " &lt;&lt; (mt19937(0) == mt19937()) &lt;&lt; endl; cout &lt;&lt; "I believe ranlux24_base(0) == ranlux24_base() should be true: " &lt;&lt; (ranlux24_base(0) == ranlux24_base()) &lt;&lt; endl; cout &lt;&lt; "run_10k( minstd_rand0(0)): " &lt;&lt; run_10k( minstd_rand0(0)) &lt;&lt; endl; cout &lt;&lt; "run_10k( mt19937(0)): " &lt;&lt; run_10k( mt19937(0)) &lt;&lt; endl; cout &lt;&lt; "run_10k(ranlux24_base(0)): " &lt;&lt; run_10k(ranlux24_base(0)) &lt;&lt; endl; } With my fixed build of Milan/VC12, I'm getting: C:\Temp&gt;cl /EHsc /nologo /W4 /MTd meow.cpp meow.cpp C:\Temp&gt;meow Using std. N3485 26.5.5 [rand.predef]/1 satisfied: true N3485 26.5.5 [rand.predef]/3 satisfied: true N3485 26.5.5 [rand.predef]/5 satisfied: true I believe minstd_rand0(0) == minstd_rand0() should be true: true I believe mt19937(0) == mt19937() should be false: false I believe ranlux24_base(0) == ranlux24_base() should be true: true run_10k( minstd_rand0(0)): 1043618065 run_10k( mt19937(0)): 1543171712 run_10k(ranlux24_base(0)): 7937952 (Note that VC11 RTM/Update 1 will suffer the bug described by [1].) If I use Boost's implementation with VC11 Update 1, I get: C:\Temp&gt;cl /EHsc /nologo /W4 /MTd /DUSE_BOOST meow.cpp /I boost-1.52.0\include meow.cpp C:\Temp&gt;meow Using boost. N3485 26.5.5 [rand.predef]/1 satisfied: true N3485 26.5.5 [rand.predef]/3 satisfied: true N3485 26.5.5 [rand.predef]/5 satisfied: true I believe minstd_rand0(0) == minstd_rand0() should be true: true I believe mt19937(0) == mt19937() should be false: false I believe ranlux24_base(0) == ranlux24_base() should be true: false run_10k( minstd_rand0(0)): 1043618065 run_10k( mt19937(0)): 1543171712 run_10k(ranlux24_base(0)): 14007167 </pre><p> Here's why I believe that ranlux24_base(0) should be equal to ranlux24_base(). ranlux24_base is a subtract_with_carry_engine. 26.5.3.3 [rand.eng.sub]/7 says: </p> <p> "explicit subtract_with_carry_engine(result_type value = default_seed); [...] linear_congruential_engine&lt;result_type, 40014u,0u,2147483563u&gt; e(value == 0u ? default_seed : value);" </p> <p> /7 doesn't refer to "value" anywhere else. Therefore, 0 should behave identically to the default_seed 19780503u. </p> <p> (For comparison, VC and Boost agree that minstd_rand0(0) == minstd_rand0(). 26.5.3.1 [rand.eng.lcong]/5 says: </p> <p> "explicit linear_congruential_engine(result_type s = default_seed); [...] If c mod m is 0 and s mod m is 0, sets the engine's state to 1, otherwise sets the engine's state to s mod m." </p> <p> The default_seed is 1u and minstd_rand0 sets c to 0, so that's why 0 behaves identically to the default_seed.) </p> <p> <a class="changeset" href="https://svn.boost.org/trac10/changeset/1" title="Import core sources for SVNmanger 0.38 ">[1]</a> <a class="ext-link" href="http://connect.microsoft.com/VisualStudio/feedback/details/776456"><span class="icon">​</span>http://connect.microsoft.com/VisualStudio/feedback/details/776456</a> </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/7951 Trac 1.4.3 Marshall Clow Wed, 30 Jan 2013 03:12:07 GMT description changed https://svn.boost.org/trac10/ticket/7951#comment:1 https://svn.boost.org/trac10/ticket/7951#comment:1 <ul> <li><strong>description</strong> modified (<a href="/trac10/ticket/7951?action=diff&amp;version=1">diff</a>) </li> </ul> <p> Fixed the formatting in the description. </p> <p> Also, I verified the same behavior occurs with clang/libc++ </p> Ticket Marshall Clow Wed, 30 Jan 2013 04:31:08 GMT <link>https://svn.boost.org/trac10/ticket/7951#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7951#comment:2</guid> <description> <p> The following change causes your test program to run successfully, and doesn't break any of the existing Boost.Random tests. </p> <p> However, someone who understands the random code should probably review this and make sure it is the correct change. </p> <pre class="wiki">Index: boost/random/subtract_with_carry.hpp =================================================================== --- boost/random/subtract_with_carry.hpp (revision 82663) +++ boost/random/subtract_with_carry.hpp (working copy) @@ -161,7 +161,7 @@ IntType, value) { typedef linear_congruential_engine&lt;uint32_t,40014,0,2147483563&gt; gen_t; - gen_t intgen(static_cast&lt;boost::uint32_t&gt;(value)); + gen_t intgen(static_cast&lt;boost::uint32_t&gt;(value == 0 ? default_seed : value)); detail::generator_seed_seq&lt;gen_t&gt; gen(intgen); seed(gen); } </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Steven Watanabe</dc:creator> <pubDate>Wed, 30 Jan 2013 04:47:10 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7951#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7951#comment:3</guid> <description> <p> This fix appears to be correct, however, </p> <p> a) Please fix subtract_with_carry_01_engine also. b) Please add a test case. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Marshall Clow</dc:creator> <pubDate>Wed, 30 Jan 2013 06:42:40 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7951#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7951#comment:4</guid> <description> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/82664" title="Fix behavior with zero seed re: '26.5.3.3 [rand.eng.sub]/7'; thanks to ...">[82664]</a>) Fix behavior with zero seed re: '26.5.3.3 [rand.eng.sub]/7'; thanks to stl@microsoft for the report; Refs <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/7951" title="#7951: Bugs: ranlux24_base(0) should be equal to ranlux24_base() (closed: fixed)">#7951</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Marshall Clow</dc:creator> <pubDate>Wed, 30 Jan 2013 06:43:10 GMT</pubDate> <title>milestone changed https://svn.boost.org/trac10/ticket/7951#comment:5 https://svn.boost.org/trac10/ticket/7951#comment:5 <ul> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.54.0</span> </li> </ul> Ticket Marshall Clow Sun, 10 Feb 2013 18:45:02 GMT owner, status changed https://svn.boost.org/trac10/ticket/7951#comment:6 https://svn.boost.org/trac10/ticket/7951#comment:6 <ul> <li><strong>owner</strong> changed from <span class="trac-author">No-Maintainer</span> to <span class="trac-author">Marshall Clow</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket Marshall Clow Mon, 11 Feb 2013 16:19:12 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/7951#comment:7 https://svn.boost.org/trac10/ticket/7951#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/82820" title="Merge Fix for zero seed in Boost.Random; Fixes #7951">[82820]</a>) Merge Fix for zero seed in Boost.Random; Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/7951" title="#7951: Bugs: ranlux24_base(0) should be equal to ranlux24_base() (closed: fixed)">#7951</a> </p> Ticket