**Section:** 28.7 [c.math] **Status:** CD1
**Submitter:** Howard Hinnant **Opened:** 2006-01-12 **Last modified:** 2016-01-28 10:19:27 UTC

**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, andscalbnbecause the second integral parameter in each of these signatures (from C99) isnotageneric parameteraccording to C99 7.22p2. The corresponding C++ overloads are intended (as far as I know) to correspond directly to C99's definition ofgeneric parameter.For similar reasons, I do not believe that the second

long doubleparameter 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

onlyaboutpow(float, int). And this is because C++98 took one route (withpowonly) 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 28.7 [c.math] p10:

The added signatures are:

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