This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.

### 550. What should the return type of `pow(float,int)` be?

Section: 26.8 [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`, 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.

[ 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 26.8 [c.math] p10:

> The added signatures are:

> >     ...
> >     float pow(float, int);
> >     ...
> >     double pow(double, int);
> >     ...
> >     long double pow(long double, int);