pow(float,int)
be?Section: 29.7 [c.math] Status: CD1 Submitter: Howard Hinnant Opened: 2006-01-12 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [c.math].
View all issues with CD1 status.
Discussion:
Assuming we adopt the C compatibility package from C99 what should be the return type of the following signature be:
? pow(float, int);
C++03 says that the return type should be float
.
TR1 and C90/99 say the return type should be double
. This can put
clients into a situation where C++03 provides answers that are not as high
quality as C90/C99/TR1. For example:
#include <math.h> int main() { float x = 2080703.375F; double y = pow(x, 2); }
Assuming an IEEE 32 bit float and IEEE 64 bit double, C90/C99/TR1 all suggest:
y = 4329326534736.390625
which is exactly right. While C++98/C++03 demands:
y = 4329326510080.
which is only approximately right.
I recommend that C++0X adopt the mixed mode arithmetic already adopted by
Fortran, C and TR1 and make the return type of pow(float,int)
be
double
.
[
Kona (2007): Other functions that are affected by this issue include
ldexp
, scalbln
, and scalbn
. We also believe that there is a typo in
26.7/10: float nexttoward(float, long double);
[sic] should be float
nexttoward(float, float);
Proposed Disposition: Review (the proposed
resolution appears above, rather than below, the heading "Proposed
resolution")
]
[Howard, post Kona:]
Unfortunately I strongly disagree with a part of the resolution from Kona. I am moving from New to Open instead of to Review because I do not believe we have consensus on the intent of the resolution.
This issue does not include
ldexp
,scalbln
, andscalbn
because the second integral parameter in each of these signatures (from C99) is not a generic parameter according to C99 7.22p2. The corresponding C++ overloads are intended (as far as I know) to correspond directly to C99's definition of generic parameter.For similar reasons, I do not believe that the second
long double
parameter ofnexttoward
, nor the return type of this function, is in error. I believe the correct signature is:float nexttoward(float, long double);which is what both the C++0X working paper and C99 state (as far as I currently understand).
This is really only about
pow(float, int)
. And this is because C++98 took one route (withpow
only) and C99 took another (with many math functions in<tgmath.h>
. The proposed resolution basically says: C++98 got it wrong and C99 got it right; let's go with C99.
[ Bellevue: ]
This signature was not picked up from C99. Instead, if one types
pow(2.0f,2)
, the promotion rules will invoke "double pow(double, double)", which generally gives special treatment for integral exponents, preserving full accuracy of the result. New proposed wording provided.
Proposed resolution:
Change 29.7 [c.math] p10:
The added signatures are:
...float pow(float, int);...double pow(double, int);...long double pow(long double, int);