Ticket #8809 (closed Bugs: fixed)

Opened 4 years ago

Last modified 4 years ago

pow(cpp_dec_float_type(-1), cpp_dec_float_type(n)) != (+-)1 for n >= 0x8000000000000000u

Reported by: Jan Bouwer <JBouwer@…> Owned by: johnmaddock
Milestone: To Be Determined Component: multiprecision
Version: Boost Development Trunk Severity: Problem
Keywords: Cc: pbristow@…, e_float@…


Function pow(const number-or-expression-template-type&, const number-or-expression-template-type&) for cpp_dec_float 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 >= 0x8000000000000000u.

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 #8711 & #8798.

Output from attached code:

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

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++.


boost_multiprecision_power_demo2.cpp (938 bytes) - added by Jan Bouwer <JBouwer@…> 4 years ago.
Demonstration of the error

Change History

Changed 4 years ago by Jan Bouwer <JBouwer@…>

Demonstration of the error

comment:1 Changed 4 years ago by Jan Bouwer <JBouwer@…>

Curiously (or not ;-)) - my std library function pow(double, double) gives the same answers ... ... perhaps shifting the scope of this elsewhere?

comment:2 Changed 4 years ago by johnmaddock

  • Cc pbristow@…, e_float@… added
  • Status changed from new to assigned

This is actually quite tricky - and hard to deal with in a consistent (across different backends) way.

The issue is that these routines need to check for integer exponent when the base is < 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.

That said we should be able to fix this up to numeric_limits<uintmax_t>::max(), 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.

comment:3 Changed 4 years ago by johnmaddock

  • Status changed from assigned to closed
  • Resolution set to fixed

(In [85008]) Fix mpfi pow function to correctly handle negative base with integer power. Fixed error handling to not return numeric_limits<>::quiet_NaN if there is no NaN supported. Fixed default pow implementation to handle integer args up to numeric_limits<uintmax_t>::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 #8809.


Add a comment

Modify Ticket

Change Properties
<Author field>
as closed
The resolution will be deleted. Next status will be 'reopened'

E-mail address and user name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.