3

With the 4.2.1 g++ compiler I get the following error:

functions.cpp:24: error: call of overloaded ‘pow(long int&, long int&)’ is ambiguous
/usr/include/architecture/i386/math.h:343: note: candidates are: double pow(double, double)
/usr/include/c++/4.2.1/cmath:373: note:                 long double std::pow(long double, int)
/usr/include/c++/4.2.1/cmath:369: note:                 float std::pow(float, int)
/usr/include/c++/4.2.1/cmath:365: note:                 double std::pow(double, int)
/usr/include/c++/4.2.1/cmath:361: note:                 long double std::pow(long double, long double)
/usr/include/c++/4.2.1/cmath:357: note:                 float std::pow(float, float)

Here's the responsible code:

long power(long a, long b) {
    if (b < 0) return 0;
    return pow(a,b);
}

However, on my 4.6.1 version there are no errors nor warnings for my code where I use two longs for the pow evaluation (even with the -Wextra flag). Why is this? And is using two longs for the pow function a mistake on my part?

Uku Loskit
  • 40,868
  • 9
  • 92
  • 93
  • looks like 4.6 added `pow(long,long)` as an extension – Anycorn Feb 14 '12 at 09:00
  • The standard says it should be double http://pubs.opengroup.org/onlinepubs/9699919799/functions/pow.html So I believe that as long as you stick with the standard you're fine, you just need to do a cast. – INS Feb 14 '12 at 09:01
  • Anycorn, could you provide a reference (post it as an answer) – Uku Loskit Feb 14 '12 at 09:02
  • I can't - the standard doesn't say anything about `pow(long,long)` - hence i assume it's an extension. – Anycorn Feb 14 '12 at 09:03
  • good work on your part to point out the difference in complilation!! – Rohit Vipin Mathews Feb 14 '12 at 09:07
  • it seems to be part of c++0x which 4.6 implemetns: http://stackoverflow.com/questions/5627030/why-was-stdpowdouble-int-removed-from-c0x – Anycorn Feb 14 '12 at 09:09
  • I would be happy to accept an answer that directly shows where this casting is done (if this at all is possible). – Uku Loskit Feb 14 '12 at 09:36

3 Answers3

3

As far as I know, pow is not confirmed to support long, long as parameters by ANSI. Please consider using double (or casts to) and if needed, round the result like this:

long int result = llround(pow((double)2L, (double)4L));
Coder02
  • 260
  • 2
  • 8
2

The problem is that there is no definition of pow that takes two longs as parameters. Because of this, the longs will be converted into some other data type, but this conversion causes ambiguity since there are many possible ways that the conversion can happen. gcc doesn't know how to interpret the call, so it gives you an error.

Pochi
  • 2,026
  • 1
  • 15
  • 11
  • I understand this. But why is problem in the older version of the compiler, but not on the newer one? – Uku Loskit Feb 14 '12 at 08:59
  • It could be that the newer version maps the call to a compatible method. For example, it might have some convention for type conversion. It might turn the longs into doubles so that it doesn't lose precision. – Pochi Feb 14 '12 at 09:02
1

Pow has only support for double and not long. Maybe in the newer version they added an implicit cast to double from long. thats the best i could think of. i havent heard of extending suport to long in pow!

Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112