Boost C++ Libraries: Ticket #6975: lexical_cast<double> produces different answers with 53-bit FPU precision https://svn.boost.org/trac10/ticket/6975 <p> For some subset of floating point strings, if you use lexical_cast&lt;double&gt;, it will produce different answers than if you use std::atof or reading from std::istringstream. However, this only happens when you use 53 bit FPU precision as opposed to 64 bit. </p> <p> A duplication program is attached, which I've only tried on g++/64 bit-Intel because of the code modifying the FPU settings. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/6975 Trac 1.4.3 Jonathan Jones <jonathan.jones@…> Fri, 08 Jun 2012 21:45:31 GMT attachment set https://svn.boost.org/trac10/ticket/6975 https://svn.boost.org/trac10/ticket/6975 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">lexical_cast.cpp</span> </li> </ul> Ticket Antony Polukhin Tue, 24 Jul 2012 18:12:05 GMT status, type, severity changed https://svn.boost.org/trac10/ticket/6975#comment:1 https://svn.boost.org/trac10/ticket/6975#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> <li><strong>type</strong> <span class="trac-field-old">Bugs</span> → <span class="trac-field-new">Support Requests</span> </li> <li><strong>severity</strong> <span class="trac-field-old">Problem</span> → <span class="trac-field-new">Cosmetic</span> </li> </ul> <p> This issue won't be fixed in nearest future (it shall be fixed in ticket <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/5660" title="#5660: Bugs: reimplement conversions to float/double/long double types (closed: wontfix)">#5660</a>) When casting to doubles, lexical_cast uses long doubles for getting better precision and assumes that long doubles precision set to 64 (default). But even with 53bit precision result is accurate enougth, so this bug is not critical. </p> <p> By the way: you shall not compare floats using == and != operatos. See <a class="ext-link" href="http://www.parashift.com/c++-faq-lite/floating-point-arith.html"><span class="icon">​</span>http://www.parashift.com/c++-faq-lite/floating-point-arith.html</a> </p> Ticket Jonathan Jones <jonathan.jones@…> Tue, 24 Jul 2012 18:36:19 GMT <link>https://svn.boost.org/trac10/ticket/6975#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6975#comment:2</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/6975#comment:1" title="Comment 1">apolukhin</a>: </p> <blockquote class="citation"> <p> This issue won't be fixed in nearest future (it shall be fixed in ticket <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/5660" title="#5660: Bugs: reimplement conversions to float/double/long double types (closed: wontfix)">#5660</a>) </p> </blockquote> <p> Do you have a rough estimate of the timeframe in which it will be fixed? </p> <blockquote class="citation"> <p> When casting to doubles, lexical_cast uses long doubles for getting better precision and assumes that long doubles precision set to 64 (default). But even with 53bit precision result is accurate enougth, so this bug is not critical. </p> </blockquote> <p> It's the double-&gt;string-&gt;double issue, as mentioned in ticket <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/5660" title="#5660: Bugs: reimplement conversions to float/double/long double types (closed: wontfix)">#5660</a>, which is problematic for us. Doubles which should be serializable to a string and back to a double with no change are returning slightly different answers from the original double. </p> <blockquote class="citation"> <p> By the way: you shall not compare floats using == and != operatos. See <a class="ext-link" href="http://www.parashift.com/c++-faq-lite/floating-point-arith.html"><span class="icon">​</span>http://www.parashift.com/c++-faq-lite/floating-point-arith.html</a> </p> </blockquote> <p> I understand that this is true in the general case, but in our case the floats we are comparing are pre-calculated numbers which are exactly representable (not approximated) in floating point. </p> <p> FWIW, we've worked around the problem by forcing lexical_cast to always use: </p> <blockquote> <p> float_types_converter_internal(T&amp; output, int /*tag*/) </p> </blockquote> <p> which doesn't seem to suffer from the same issue. It's only lcast_ret_float&lt;Traits&gt; which has the problem. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Antony Polukhin</dc:creator> <pubDate>Tue, 24 Jul 2012 20:17:53 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6975#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6975#comment:3</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/6975#comment:2" title="Comment 2">Jonathan Jones &lt;jonathan.jones@…&gt;</a>: </p> <blockquote class="citation"> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/6975#comment:1" title="Comment 1">apolukhin</a>: </p> <blockquote class="citation"> <p> This issue won't be fixed in nearest future (it shall be fixed in ticket <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/5660" title="#5660: Bugs: reimplement conversions to float/double/long double types (closed: wontfix)">#5660</a>) </p> </blockquote> <p> Do you have a rough estimate of the timeframe in which it will be fixed? </p> </blockquote> <p> I do not think that it would be fixed in nearest two releases of boost. </p> <p> &lt;snip&gt; </p> <blockquote class="citation"> <p> FWIW, we've worked around the problem by forcing lexical_cast to always use: </p> <blockquote> <p> float_types_converter_internal(T&amp; output, int /*tag*/) </p> </blockquote> <p> which doesn't seem to suffer from the same issue. It's only lcast_ret_float&lt;Traits&gt; which has the problem. </p> </blockquote> <p> It is good enough solution, but it may also return slightly different answers for some numbers on MSVC, older versions of GCC and non popular compilers. And this solution is slightly slower (but I do not think that you will notice it) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Antony Polukhin</dc:creator> <pubDate>Mon, 09 Mar 2015 09:36:23 GMT</pubDate> <title>status, milestone changed; resolution set https://svn.boost.org/trac10/ticket/6975#comment:4 https://svn.boost.org/trac10/ticket/6975#comment:4 <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> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.58.0</span> </li> </ul> <p> Since Boost 1.58 lexical_cast must use converters from Standard Library, so that issue must be already resolved on Standard Library level. </p> Ticket