Ambiguous call to pow()

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Ganon11
    Recognized Expert Specialist
    • Oct 2006
    • 3651

    Ambiguous call to pow()

    I was working on a program this morning that required me to use the pow function (to compute 2^i at one point, and 3^i at another). I used the following code:

    [CODE=cpp]std::vector<int > increments(stat ic_cast<int>(lo g(a.size() + 1)/log(2)));
    for (int i = 0; i < increments.size (); i++)
    increments[i] = pow(2, i);[/CODE]

    and got an error message saying "The call to pow(int, int&) is ambiguous. Candidates are:" and proceeded to list all sorts of pow functions using doubles, long doubles, floats, etc., but no int or long int versions!

    Eventually I had to change that last line to

    [code=cpp]increments[i] = static_cast<int >(pow(static_ca st<double>(2), i));[/code]

    in order to get the dang thing to compile. It produced expected results, but still frustrated me.

    Why is there no pow(int, int) function available in the cmath header file?
  • RRick
    Recognized Expert Contributor
    • Feb 2007
    • 463

    #2
    For most of the functions in cmath, it doesn't make sense to have an integer version. Functions like sine and sqrt don't transfer well to integer.

    They did make a version of abs for integers and longs, but pow has been left behind.

    Since you are dealing with floating point values for pow, you might run into round off errors when converting to ints. It is advisable to add a small delta to pow before converting to an int.
    [code=cpp]increments[i] = static_cast<int >(pow(static_ca st<double>(2), i)+.005);[/code]

    Comment

    • Ganon11
      Recognized Expert Specialist
      • Oct 2006
      • 3651

      #3
      I agree that sine, sqrt, and exp don't need int versions, but it makes perfect sense to raise an integer to an integer power and expect an integer to result.

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        I recommend that you not cast in C++ unless you are on fire.

        This is not a fire.

        Just write a

        int pow(int, int);

        as suggested and off you go.

        You have to remember that pow() is an old C function and C does not allow for function overloading so everyone had to type cast. Unfortunately, that is an extremely bad habit in C++.

        The C++ pow() requires you use a valarray rather than an int. Personally, I think you will have your function working before you understand how to use valarray.

        Comment

        • Ganon11
          Recognized Expert Specialist
          • Oct 2006
          • 3651

          #5
          All right, I'll keep that in mind for future projects.

          Will simply putting a declaration of int pow(int, int) at the top of my program work? Or will I have to provide a definition for the function?

          EDIT: Wrote a simple test program to find out that I did need to provide a declaration, so I used the fast exponentiation method we learned in class:

          [CODE=cpp]int pow(int base, int power) {
          if (power == 0) return 1;
          if (power == 1) return base;
          if (power % 2 == 0) return pow(base * base, power / 2);
          if (power % 2 == 1) return base * pow(base * base, power / 2);
          }[/CODE]

          Annoying, if you ask me.

          Comment

          • weaknessforcats
            Recognized Expert Expert
            • Mar 2007
            • 9214

            #6
            Originally posted by Ganon11
            Will simply putting a declaration of int pow(int, int) at the top of my program work? Or will I have to provide a definition for the function?
            The declaration will be enough for the compile step. But you will need the definiton to be compiled for the link step.

            Your pow() should allow for negative exponents.

            Comment

            • Laharl
              Recognized Expert Contributor
              • Sep 2007
              • 849

              #7
              I had the same result doing this lab, and eventually got it without nasty casting:

              Code:
              pow(2.0, i);

              Comment

              • weaknessforcats
                Recognized Expert Expert
                • Mar 2007
                • 9214

                #8
                Originally posted by Laharl
                I had the same result doing this lab, and eventually got it without nasty casting:


                Code: ( text )
                pow(2.0, i);
                It still is a cast. This calls:
                [code=c]
                double pow(double, double);
                [/code]

                The int i is automatically cast as a double using the compiler's C++ promotion rules. The probem is that the result is a double when an int is desired.

                Comment

                • Laharl
                  Recognized Expert Contributor
                  • Sep 2007
                  • 849

                  #9
                  If you know that only whole number values will be returned or that a truncated value will be sufficient, you can use floor() to take care of that.

                  Comment

                  • dhodder
                    New Member
                    • Jan 2012
                    • 1

                    #10


                    Look at the definition for ::pow. I don't see int pow(int, int). Where are you getting this from?

                    Why not cast in c++? If you know what you're doing - it's no problem.

                    In what documentation is advising you not to cast? or is this just your personal opinion?


                    Originally posted by weaknessforcats
                    I recommend that you not cast in C++ unless you are on fire.

                    This is not a fire.

                    Just write a

                    int pow(int, int);

                    as suggested and off you go.

                    You have to remember that pow() is an old C function and C does not allow for function overloading so everyone had to type cast. Unfortunately, that is an extremely bad habit in C++.

                    The C++ pow() requires you use a valarray rather than an int. Personally, I think you will have your function working before you understand how to use valarray.

                    Comment

                    Working...