Boost C++ Libraries: Ticket #6627: nonfinite_num_put formatting of 0.0 is incorrect https://svn.boost.org/trac10/ticket/6627 <p> We noticed time strings changed from displaying 00:00.00 to 00:00000 after installing the nonfinite_num facets globally. It appears that formatting for 0.0 isn't behaving as it should when precision and fixed are involved (and potentially others). </p> <pre class="wiki">#include &lt;boost/math/special_functions/nonfinite_num_facets.hpp&gt; #include &lt;iomanip&gt; #include &lt;iostream&gt; #include &lt;sstream&gt; void writeZero( std::ostream&amp; stream ) { stream &lt;&lt; std::fixed &lt;&lt; std::setw( 5 ) &lt;&lt; std::setfill( '0' ) &lt;&lt; std::setprecision( 2 ) &lt;&lt; 0.0; } int main() { std::stringstream standardStream; writeZero( standardStream ); std::cout &lt;&lt; standardStream.str() &lt;&lt; std::endl; std::stringstream nonfiniteStream; std::locale nonfiniteNumLocale( std::locale(), new boost::math::nonfinite_num_put&lt; char &gt;() ); nonfiniteStream.imbue( nonfiniteNumLocale ); writeZero( nonfiniteStream ); std::cout &lt;&lt; nonfiniteStream.str() &lt;&lt; std::endl; return 0; } // OUTPUT: // // 00.00 // 00000 </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/6627 Trac 1.4.3 John Maddock Wed, 29 Feb 2012 08:32:31 GMT owner changed https://svn.boost.org/trac10/ticket/6627#comment:1 https://svn.boost.org/trac10/ticket/6627#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">John Maddock</span> to <span class="trac-author">Paul A. Bristow</span> </li> </ul> Ticket Paul A. Bristow Wed, 29 Feb 2012 09:43:51 GMT <link>https://svn.boost.org/trac10/ticket/6627#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6627#comment:2</guid> <description> <p> OK, looks to be a bug. Will look at this in a day or few. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Paul A. Bristow</dc:creator> <pubDate>Wed, 29 Feb 2012 16:28:16 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6627#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6627#comment:3</guid> <description> <p> Well this looks a bit more complicated than I feared. There seems to be a difference between sending to cout (00000) and a stringstream (00.00). </p> <pre class="wiki"> cout &lt;&lt; std::fixed &lt;&lt; std::setw( 5 ) &lt;&lt; std::setfill( '0' ) &lt;&lt; std::setprecision( 2 ) &lt;&lt; 0.0 &lt;&lt; endl; // 00000 std::stringstream astream; astream &lt;&lt; std::fixed &lt;&lt; std::setw( 5 ) &lt;&lt; std::setfill( '0' ) &lt;&lt; std::setprecision( 2 ) &lt;&lt; 0.0; // 00.00 </pre><p> which leaves me more than a bit wary of making any precipitate changes to Johan Rade's nonfinite_num_put code :-( (Before fools step in where angels fear to tread? - again!) </p> <p> I'd like you to consider if it might be safer to circumnavigate this 'feature'? </p> <p> Paul </p> </description> <category>Ticket</category> </item> <item> <author>krwalker@…</author> <pubDate>Thu, 01 Mar 2012 23:05:49 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6627#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6627#comment:4</guid> <description> <p> Do you have those reversed? </p> <pre class="wiki">int main() { std::locale::global( std::locale( std::locale(), new boost::math::nonfinite_num_put&lt; char &gt;() ) ); writeZero( std::cout ); std::cout &lt;&lt; std::endl; // 00.00 std::stringstream astream; writeZero( astream ); std::cout &lt;&lt; astream.str() &lt;&lt; std::endl; // 00000 return 0; } </pre><p> "Changing the global locale does not change the locales of pre-existing streams. If you want to imbue the new global locale on cout, you should call std::cout.imbue(locale()) after calling std::locale::global()." -- <a class="ext-link" href="http://stdcxx.apache.org/doc/stdlibug/24-3.html"><span class="icon">​</span>http://stdcxx.apache.org/doc/stdlibug/24-3.html</a> </p> </description> <category>Ticket</category> </item> <item> <author>krwalker@…</author> <pubDate>Thu, 01 Mar 2012 23:38:40 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6627#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6627#comment:5</guid> <description> <p> I may have a patch that makes the FP_ZERO case only output the '-' if ( flags_ &amp; signed_zero ). It then reduces iosb.width() by 1 and delegates to std::num_put. </p> </description> <category>Ticket</category> </item> <item> <author>krwalker@…</author> <pubDate>Fri, 02 Mar 2012 00:05:55 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/6627 https://svn.boost.org/trac10/ticket/6627 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">nonfinite_num_put_zero_formatting.patch</span> </li> </ul> Ticket Paul A. Bristow Fri, 02 Mar 2012 10:05:11 GMT <link>https://svn.boost.org/trac10/ticket/6627#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6627#comment:6</guid> <description> <p> OK - if you are keen to fix this properly, I'll try to get to look at this more closely, including writing all the several test cases to check I haven't introduced another bug in fixing this one. You could also email me privately. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Paul A. Bristow</dc:creator> <pubDate>Fri, 02 Mar 2012 11:51:42 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/6627 https://svn.boost.org/trac10/ticket/6627 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">nonfinite_num_facets_formatting_2.hpp.patch</span> </li> </ul> <p> Patch to try to treat unsigned zero as normal value. </p> Ticket Paul A. Bristow Fri, 02 Mar 2012 11:54:48 GMT <link>https://svn.boost.org/trac10/ticket/6627#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6627#comment:7</guid> <description> <p> I have yet to fully understand how this code is intended to work. </p> <p> You patch seems rather complicated? </p> <p> Does my 2nd patch (that simply aims to treat an unsigned zero as a normal value) work for you ? </p> <p> (While I write some tests). </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Paul A. Bristow</dc:creator> <pubDate>Thu, 08 Mar 2012 19:16:40 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6627#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6627#comment:8</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/6627#comment:7" title="Comment 7">pbristow</a>: </p> <p> I have now written a much larger collection of tests (though there are an almost infinite number of possible combinations of ostream options like precision, width, letf right, internal, showpos showpoint :-( </p> <p> And committed a revised version (using code from KR Walker) that passes on MSVC 10 these tests with the signed_zero flag set (and also handles inf and nan as before). </p> <p> I am not entirely convinced that there is really a need for a signed_zero flag at all. </p> <p> Are there really any platforms/libraries still out there that do not output negative zero correctly as -0? </p> <p> Feedback welcome. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Paul A. Bristow</dc:creator> <pubDate>Fri, 23 Mar 2012 09:57:36 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6627#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6627#comment:9</guid> <description> <p> Tests reveal that, for some combinations of options, there is a difference in output between Dinkumware STL and other STL implementations, for example: </p> <p> #if defined(_CPPLIB_VER) &amp;&amp; (_CPPLIB_VER &gt;= 306) <em> Dinkumware outputs "0.00" </em></p> <blockquote> <p> CHECKOUT(std::showpoint &lt;&lt; 0., "0.000000"); <em> std::setprecision(6) CHECKOUT(std::setprecision(2) &lt;&lt; std::showpoint &lt;&lt; 0., "0.00"); </em></p> </blockquote> <p> #else <em> others output "0.0" </em></p> <blockquote> <p> CHECKOUT(std::showpoint &lt;&lt; 0., "0.00000"); <em> std::setprecision(6) CHECKOUT(std::setprecision(2) &lt;&lt; std::showpoint &lt;&lt; 0., "0.0"); </em></p> </blockquote> <p> #endif </p> <p> I am unclear if either of these is 'wrong' according the C/C++ Standards, but this is outside control of Boost.Math code, so I propose to declare this fixed in trunk. </p> <p> (There are also some STL libraries that use two exponent digits rather than three - this is standards conformant). </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Paul A. Bristow</dc:creator> <pubDate>Sun, 22 Apr 2012 11:53:15 GMT</pubDate> <title>status, version changed; resolution set https://svn.boost.org/trac10/ticket/6627#comment:10 https://svn.boost.org/trac10/ticket/6627#comment:10 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost 1.48.0</span> → <span class="trac-field-new">Boost 1.50.0</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> Since the C++ IO Library Standard is somewhat permissive in output, and the support for signed zero is platform dependent, it is not believed possible to provide a solution which is exactly portable (producing idential output) over all platforms. It is probably wise to avoid using the signed_zero flag. </p> Ticket