Opened 4 years ago

Closed 4 years ago

#8809 closed Bugs (fixed)

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

Reported by: Jan Bouwer <JBouwer@…> Owned by: John Maddock
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++.

Attachments (1)

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

Download all attachments as: .zip

Change History (4)

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 John Maddock

Cc: pbristow@… e_float@… added
Status: newassigned

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 John Maddock

Resolution: fixed
Status: assignedclosed

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

Modify Ticket

Change Properties
Set your email in Preferences
as closed The owner will remain John Maddock.
The resolution will be deleted.

Add Comment

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

Note: See TracTickets for help on using tickets.