Boost C++ Libraries: Ticket #11056: karma real generator does not produce enough digits to guarantee round trip through spirit https://svn.boost.org/trac10/ticket/11056 <p> The real_inserter::call_n method in <a class="ext-link" href="http://svn.boost.org/svn/boost/trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp"><span class="icon">​</span>http://svn.boost.org/svn/boost/trunk/boost/spirit/home/karma/numeric/detail/real_utils.hpp</a> limits the number of output characters representing a real (floating-point) number of type U to std::numeric_limits&lt;U&gt;::digits10. However, digits10 represents the number of decimal digits that are guaranteed to survive a round-trip conversion for the type. This is not the same as the number of decimal digits that a type can represent, which is std::numeric_limits&lt;U&gt;::max_digits10 (in c++11). </p> <p> The following code describes the problem when attempting to round-trip using karma and spirit vs. using stringstreams, picking a particular value that fails: </p> <div class="wiki-code"><div class="code"><pre><span class="c1">// define a new real number formatting policy</span> <span class="k">struct</span> <span class="nl">precise_policy</span> <span class="p">:</span> <span class="n">real_policies</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span> <span class="p">{</span> <span class="c1">// Limited to digits10, no matter what I put here</span> <span class="k">static</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">precision</span><span class="p">(</span><span class="kt">float</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;::</span><span class="n">max_digits10</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="kt">float</span> <span class="n">a</span> <span class="o">=</span> <span class="mf">135.477005</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">stringstream</span> <span class="n">ss</span><span class="p">;</span> <span class="n">ss</span><span class="p">.</span><span class="n">precision</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;::</span><span class="n">max_digits10</span><span class="p">);</span> <span class="n">ss</span> <span class="o">&lt;&lt;</span> <span class="n">a</span><span class="p">;</span> <span class="kt">float</span> <span class="n">b</span><span class="p">;</span> <span class="n">ss</span> <span class="o">&gt;&gt;</span> <span class="n">b</span><span class="p">;</span> <span class="n">assert</span><span class="p">(</span><span class="n">a</span> <span class="o">==</span> <span class="n">b</span><span class="p">);</span> <span class="c1">// succeeds</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">st</span><span class="p">;</span> <span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="n">back_insert_iterator</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">sink_type</span><span class="p">;</span> <span class="n">sink_type</span> <span class="nf">sink</span><span class="p">(</span><span class="n">st</span><span class="p">);</span> <span class="k">typedef</span> <span class="n">real_generator</span><span class="o">&lt;</span><span class="kt">float</span><span class="p">,</span> <span class="n">precise_policy</span><span class="o">&gt;</span> <span class="n">precise_type</span><span class="p">;</span> <span class="n">precise_type</span> <span class="k">const</span> <span class="n">precise</span> <span class="o">=</span> <span class="n">precise_type</span><span class="p">();</span> <span class="n">generate</span><span class="p">(</span><span class="n">sink</span><span class="p">,</span> <span class="n">precise</span><span class="p">,</span> <span class="n">a</span><span class="p">);</span> <span class="kt">float</span> <span class="n">c</span><span class="p">;</span> <span class="n">parse</span><span class="p">(</span><span class="n">st</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">st</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span> <span class="n">float_</span><span class="p">,</span> <span class="n">c</span><span class="p">);</span> <span class="n">assert</span><span class="p">(</span><span class="n">a</span> <span class="o">==</span> <span class="n">c</span><span class="p">);</span> <span class="c1">// fails, even though enough digits were requested</span> <span class="c1">// with precise_policy!</span> </pre></div></div><p> One solution would be to change the maximum number of digits to std::numeric_limits&lt;U&gt;::max_digits10 (or the equivalent in non-c++11 code). </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11056 Trac 1.4.3 reallyasi9@… Wed, 25 Feb 2015 05:15:37 GMT keywords set https://svn.boost.org/trac10/ticket/11056#comment:1 https://svn.boost.org/trac10/ticket/11056#comment:1 <ul> <li><strong>keywords</strong> karma real_generator added </li> </ul> Ticket Joel de Guzman Sun, 14 Mar 2021 19:56:00 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/11056#comment:2 https://svn.boost.org/trac10/ticket/11056#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> fixed in <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/586" title="#586: Patches: iostreams // file_descriptor::seek BUG on files &gt; 4 GB (closed: fixed)">#586</a> <a class="ext-link" href="https://github.com/boostorg/spirit/pull/586"><span class="icon">​</span>https://github.com/boostorg/spirit/pull/586</a> </p> Ticket