Title
What should the return type of pow(float,int) be?
Status
cd1
Section
[c.math]
Submitter
Howard Hinnant

Created on 2006-01-12.00:00:00 last changed 172 months ago

Messages

Date: 2010-10-21.18:28:33

Proposed resolution:

Change [c.math] p10:

The added signatures are:

...
float pow(float, int);
...
double pow(double, int);
...
long double pow(long double, int);
Date: 2010-10-21.18:28:33

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

Date: 2010-10-21.18:28:33

[ 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, and scalbn 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 of nexttoward, 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 (with pow 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.

Date: 2010-10-21.18:28:33

[ 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") ]

Date: 2006-01-12.00:00:00

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.

History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg3027
2010-10-21 18:28:33adminsetmessages: + msg3026
2010-10-21 18:28:33adminsetmessages: + msg3025
2010-10-21 18:28:33adminsetmessages: + msg3024
2006-01-12 00:00:00admincreate