Boost C++ Libraries: Ticket #8809: pow(cpp_dec_float_type(-1), cpp_dec_float_type(n)) != (+-)1 for n >= 0x8000000000000000u https://svn.boost.org/trac10/ticket/8809 <p> Function <em>pow(const number-or-expression-template-type&amp;, const number-or-expression-template-type&amp;)</em> for <em>cpp_dec_float</em> backend gives wrong answer when used with base -1 and a positive exponent equivalent to a type (unsigned 64bit on my platform) with the high bit set; i.e. an exponent &gt;= 0x8000000000000000u. </p> <p> The answers suggest that the exponent may be interpreted as its 2's complement-negative value (not confirmed) - see sample output below. This may be related to <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/8711" title="#8711: Bugs: cpp_int fails to construct correctly from minimum negative (closed: fixed)">#8711</a> &amp; <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/8798" title="#8798: Bugs: pow(cpp_dec_float_type(0), cpp_dec_float_type(n)) != 0 for n &gt; 1 (closed: fixed)">#8798</a>. </p> <p> Output from attached code: </p> <pre class="wiki">pow(-1, 9.22337e+18) = -0.00127263 pow(-1, 9.22337e+18) = -0.00127263 pow(-1, 1.84467e+19) = 0 pow(-1, 1.84467e+19) = 0 pow(-1, 9.22337e+18) = -0.00127263 pow(-1, 9.22337e+18) = -0.00127263 pow(-1, 1.84467e+19) = 0 pow(-1, 1.84467e+19) = 0 </pre><p> Tested against trunk rev 8490 with clang (Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)) target: x86_64-apple-darwin12.4.0 with: -std=c++11 -stdlib=libc++. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/8809 Trac 1.4.3 Jan Bouwer <JBouwer@…> Wed, 10 Jul 2013 12:08:03 GMT attachment set https://svn.boost.org/trac10/ticket/8809 https://svn.boost.org/trac10/ticket/8809 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost_multiprecision_power_demo2.cpp</span> </li> </ul> <p> Demonstration of the error </p> Ticket Jan Bouwer <JBouwer@…> Wed, 10 Jul 2013 12:19:00 GMT <link>https://svn.boost.org/trac10/ticket/8809#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8809#comment:1</guid> <description> <p> Curiously (or not ;-)) - my std library function <em>pow(double, double)</em> gives the same answers ... ... perhaps shifting the scope of this elsewhere? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>John Maddock</dc:creator> <pubDate>Wed, 10 Jul 2013 17:44:00 GMT</pubDate> <title>status changed; cc set https://svn.boost.org/trac10/ticket/8809#comment:2 https://svn.boost.org/trac10/ticket/8809#comment:2 <ul> <li><strong>cc</strong> <span class="trac-author">pbristow@…</span> <span class="trac-author">e_float@…</span> added </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> <p> This is actually quite tricky - and hard to deal with in a consistent (across different backends) way. </p> <p> The issue is that these routines need to check for integer exponent when the base is &lt; 1, but this is hard to do when the exponent becomes overly large. A related point is that once the exponent becomes sufficiently large it's no longer possible to determine whether it is even or odd (needed for the sign of the result) as the final digit has dropped off the end of the floating point type. </p> <p> That said we should be able to fix this up to <code>numeric_limits&lt;uintmax_t&gt;::max()</code>, and this has uncovered some broken error handling too. I'm CC'ing Chris and Paul into this issue in case they have some ideas. </p> Ticket John Maddock Fri, 12 Jul 2013 16:13:36 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/8809#comment:3 https://svn.boost.org/trac10/ticket/8809#comment:3 <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/85008" title="Fix mpfi pow function to correctly handle negative base with integer ...">[85008]</a>) Fix mpfi pow function to correctly handle negative base with integer power. Fixed error handling to not return numeric_limits&lt;&gt;::quiet_NaN if there is no NaN supported. Fixed default pow implementation to handle integer args up to numeric_limits&lt;uintmax_t&gt;::max(). Fixed error handling in default pow implementation to return NaN for too large exponents (can't tell if they're integers or even or odd) and negative bases. Fixed array subscript bug in cpp_dec_float. Greatly increased pow testing. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/8809" title="#8809: Bugs: pow(cpp_dec_float_type(-1), cpp_dec_float_type(n)) != (+-)1 for n &gt;= ... (closed: fixed)">#8809</a>. </p> Ticket