Opened 9 years ago
Closed 9 years ago
#8809 closed Bugs (fixed)
pow(cpp_dec_float_type(-1), cpp_dec_float_type(n)) != (+-)1 for n >= 0x8000000000000000u
Reported by: | Owned by: | John Maddock | |
---|---|---|---|
Milestone: | To Be Determined | Component: | multiprecision |
Version: | Boost Development Trunk | Severity: | Problem |
Keywords: | Cc: | pbristow@…, e_float@… |
Description
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)
Change History (4)
by , 9 years ago
Attachment: | boost_multiprecision_power_demo2.cpp added |
---|
comment:1 by , 9 years ago
Curiously (or not ;-)) - my std library function pow(double, double) gives the same answers ... ... perhaps shifting the scope of this elsewhere?
comment:2 by , 9 years ago
Cc: | added |
---|---|
Status: | new → 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 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
(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.
Demonstration of the error