Problem with Exponent program

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Protoman

    #1

    Problem with Exponent program

    I'm getting a compilation error with this program, something about the
    instation of invArg; here's the code:

    #include <iostream>
    #include <cstdlib>
    using namespace std;

    template<class T>
    class invArg
    {
    public:
    invArg(T& arg):inv(arg){}
    virtual void Write()const{co ut << inv << endl;}
    private:
    T inv;
    };

    template<class T>
    class Exp
    {
    public:
    T operator()(cons t T& base, T exp)throw(invAr g<T>)
    {
    if(exp<0)
    1/operator()(base ,exp);
    else if(base==0)
    throw invArg<T>(base) ;
    else
    {
    T ret=1;
    for(;exp--;)
    base*=exp;
    return ret;
    }
    }
    };

    int main()
    {
    for(;;)
    {
    try
    {
    long double base,exp;
    cout << "Enter a base and an exponent: " << endl;
    cin >> base >> exp;
    cout << base <<"^" << exp << "=" << fixed << Exp<long
    double>()(base, exp) << endl;
    }
    catch(invArg<lo ng double>& inv)
    {
    inv.Write();
    }
    system("PAUSE") ;
    return 0;
    }
    }

    I think the type checking is too strong; any suggestions? Thanks!!!

  • Martin Vejnar

    #2
    Re: Problem with Exponent program

    Protoman wrote:[color=blue]
    > I'm getting a compilation error with this program, something about the
    > instation of invArg; here's the code:[/color]

    "Something about..." is not a very good description of an error message.
    [color=blue]
    > template<class T>
    > class invArg
    > {
    > public:
    > invArg(T& arg):inv(arg){}
    > virtual void Write()const{co ut << inv << endl;}
    > private:
    > T inv;
    > };[/color]

    The constructor should take `const T &`. It doesn't now and that is why

    throw invArg<T> (base);

    fails to compile; `base` is `const T &`.

    I would also consider making the constructor `explicit`.

    Martin.

    Comment

    • Protoman

      #3
      Re: Problem with Exponent program

      Here's the new code; now after I type the numbers, the program closes.
      What do I do?

      #include <iostream>
      #include <cstdlib>
      using namespace std;

      template<class T>
      class invArg
      {
      public:
      explicit invArg(const T& arg):inv(arg){}
      virtual void Write()const{co ut << inv << endl;}
      private:
      T inv;
      };

      template<class T>
      class Exp
      {
      public:
      T operator()(cons t T& base, T exp)throw(invAr g<T>)
      {
      if(exp<0)
      1/operator()(base ,exp);
      else if(base==0)
      throw invArg<T>(base) ;
      else
      {
      T ret=1;
      for(;exp--;)
      exp*=base;
      return ret;
      }
      }
      };

      int main()
      {
      try
      {
      long double base,exp;
      cout << "Enter a base and an exponent: " << endl;
      cin >> base >> exp;
      cout << base <<"^" << exp << "=" << fixed << Exp<long
      double>()(base, exp) << endl;
      system("PAUSE") ;
      return 0;
      }
      catch(invArg<co nst long double>& inv)
      {
      inv.Write();
      }
      }

      Any suggestions? Thanks!!!

      Comment

      • Thomas Tutone

        #4
        Re: Problem with Exponent program

        Protoman wrote:[color=blue]
        > Here's the new code; now after I type the numbers, the program closes.
        > What do I do?[/color]

        First, please indent your program properly. You make it VERY hard to
        follow your logic when everything is on the left margin.

        Second, how can we know if you don't tell us what the numbers are that
        resulted in the behavior?
        [color=blue]
        > #include <iostream>
        > #include <cstdlib>
        > using namespace std;
        >
        > template<class T>
        > class invArg
        > {
        > public:
        > explicit invArg(const T& arg):inv(arg){}
        > virtual void Write()const{co ut << inv << endl;}
        > private:
        > T inv;
        > };
        >
        > template<class T>
        > class Exp
        > {
        > public:
        > T operator()(cons t T& base, T exp)throw(invAr g<T>)
        > {
        > if(exp<0)
        > 1/operator()(base ,exp);[/color]

        What on earth is the above supposed to do? Are you missing a return
        statement? In any case, if exp is negative, you get an infinite loop
        until you overrun your stack. Please explain what you intended with
        the above.
        [color=blue]
        > else if(base==0)
        > throw invArg<T>(base) ;
        > else
        > {
        > T ret=1;
        > for(;exp--;)
        > exp*=base;
        > return ret;[/color]

        ??? You initialize ret to 1, then you never change ret. Therefore, the
        above will always return 1. Meanwhile, exp gets bigger and bigger -
        how will it ever get to zero?
        [color=blue]
        > }
        > }
        > };
        >
        > int main()
        > {
        > try
        > {
        > long double base,exp;
        > cout << "Enter a base and an exponent: " << endl;
        > cin >> base >> exp;
        > cout << base <<"^" << exp << "=" << fixed << Exp<long
        > double>()(base, exp) << endl;
        > system("PAUSE") ;
        > return 0;
        > }
        > catch(invArg<co nst long double>& inv)
        > {
        > inv.Write();[/color]

        Probably you should insert another system("PAUSE") here, in case your
        program throws (which I assume it did).
        [color=blue]
        > }
        > }[/color]

        You know, I think it's fairly likely you're just a troll, but I suppose
        you are mildly entertaining.

        Best regards,

        Tom

        Comment

        • Protoman

          #5
          Re: Problem with Exponent program

          OK, I'm trying to make it work like exponents in algebra work; i.e.
          negative exponents are reciprocals of their positive counterparts,
          fractional exponents are roots, like that. And I'm trying to make it
          throw if one of these four things: the base is 0, both the base and exp
          is 0, or its 0 rasised to zero or a negative. Does that make it
          clearer? Thanks!!!

          Comment

          • Howard

            #6
            Re: Problem with Exponent program


            "Protoman" <Protoman2050@g mail.com> wrote in message
            [color=blue]
            > T operator()(cons t T& base, T exp)throw(invAr g<T>)
            > {
            > if(exp<0)
            > 1/operator()(base ,exp);
            > else if(base==0)
            > throw invArg<T>(base) ;
            > else
            > {
            > T ret=1;
            > for(;exp--;)
            > exp*=base;
            > return ret;
            > }
            > }
            >[/color]

            Pass a negative number as the exponent to that function. What happens? It
            calls operator() again, passing it the SAME values. Which means it passes a
            negative value for exp again. So then what happens...?

            Also, look at the loop. What's it doing? Look carefully, especially at how
            ret gets its value...

            -Howard



            Comment

            • Protoman

              #7
              Re: Problem with Exponent program


              Howard wrote:[color=blue]
              > "Protoman" <Protoman2050@g mail.com> wrote in message
              >[color=green]
              > > T operator()(cons t T& base, T exp)throw(invAr g<T>)
              > > {
              > > if(exp<0)
              > > 1/operator()(base ,exp);
              > > else if(base==0)
              > > throw invArg<T>(base) ;
              > > else
              > > {
              > > T ret=1;
              > > for(;exp--;)
              > > exp*=base;
              > > return ret;
              > > }
              > > }
              > >[/color]
              >
              > Pass a negative number as the exponent to that function. What happens? It
              > calls operator() again, passing it the SAME values. Which means it passes a
              > negative value for exp again. So then what happens...?
              >[/color]

              OK, this should work, but how do I get it to stop closing after I
              input?

              #include <iostream>
              #include <cstdlib>
              using namespace std;

              template<class T>
              class invArg
              {
              public:
              explicit invArg(const T& arg):inv(arg){}
              virtual void Write()const{co ut << inv << endl;}
              private:
              T inv;
              };

              template<class T>
              class Exp
              {
              public:
              T operator()(cons t T& base, T exp)throw(invAr g<T>)
              {
              if(exp<0)
              goto neg;
              else if(base==0)
              throw invArg<T>(base) ;
              else
              {
              T ret=1;
              for(;exp--;)
              ret*=base;
              return ret;
              }
              neg:
              {
              T ret=1;
              for(;exp--;)
              ret*=base;
              return 1/ret;
              }
              }
              };

              int main()
              {
              try
              {
              long double base,exp;
              cout << "Enter a base and an exponent: " << endl;
              cin >> base >> exp;
              cout << base <<"^" << exp << "=" << fixed << Exp<long
              double>()(base, exp) << endl;
              system("PAUSE") ;
              return 0;
              }
              catch(invArg<co nst long double>& inv)
              {
              inv.Write();
              }
              }

              Any suggestions? Thanks!!![color=blue]
              > Also, look at the loop. What's it doing? Look carefully, especially at how
              > ret gets its value...
              >
              > -Howard[/color]

              Comment

              • int2str@gmail.com

                #8
                Re: Problem with Exponent program


                Protoman wrote:[color=blue]
                > OK, this should work, but how do I get it to stop closing after I
                > input?[/color]

                Is this a joke?
                What do you mean by "work"?

                See comments below.
                [color=blue]
                >
                > #include <iostream>
                > #include <cstdlib>
                > using namespace std;
                >
                > template<class T>
                > class invArg
                > {
                > public:
                > explicit invArg(const T& arg):inv(arg){}
                > virtual void Write()const{co ut << inv << endl;}[/color]

                It's not very helpful to just print the argument without any message
                now, is it?
                [color=blue]
                > private:
                > T inv;
                > };
                >
                > template<class T>
                > class Exp[/color]

                Why make this a class and not a freestanding function?

                You are not using any object orientated features here that would
                require this to be a class. Don't do it simply for the sake of saying
                "I made a class".
                [color=blue]
                > {
                > public:
                > T operator()(cons t T& base, T exp)throw(invAr g<T>)[/color]

                Why is exp not a const reference? It should be.
                [color=blue]
                > {
                > if(exp<0)
                > goto neg;[/color]

                GOTO??? There is absolutely no need to use goto to achive the desired
                program flow here. When you code, don't think about the exceptions
                first, think about the commonalities.. ..
                [color=blue]
                > else
                > {
                > T ret=1;
                > for(;exp--;)[/color]

                A while loop would be way more appropriate here.

                But the bigger issue is that this can only work for integer values of
                exp. I.e. if exp is a fraction (which it can be based on you declaring
                it as long double), this code will endless-loop.
                [color=blue]
                > ret*=base;
                > return ret;
                > }
                > neg:
                > {
                > T ret=1;
                > for(;exp--;)
                > ret*=base;
                > return 1/ret;[/color]

                You are performing the same actions here as in the "positive" case, but
                only invert the result. This can be done way simpler without using
                goto.
                [color=blue]
                > }
                > }
                > };
                >
                > int main()
                > {
                > try
                > {
                > long double base,exp;
                > cout << "Enter a base and an exponent: " << endl;
                > cin >> base >> exp;[/color]

                You are never checking if this succeeded (cin still valid)...
                [color=blue]
                > cout << base <<"^" << exp << "=" << fixed << Exp<long
                > double>()(base, exp) << endl;
                > system("PAUSE") ;[/color]

                This is not portable.
                If you really have to do this (I'm sure your teacher would be ok
                without it), just to a getline( cin, temp); or so...
                [color=blue]
                > return 0;
                > }
                > catch(invArg<co nst long double>& inv)[/color]

                Wrong....

                catch( const invArg<long double>& inv)
                [color=blue]
                > {
                > inv.Write();
                > }
                > }[/color]

                Comment

                • Howard

                  #9
                  Re: Problem with Exponent program


                  "Protoman" <Protoman2050@g mail.com> wrote in message
                  news:1135033130 .812182.263630@ g44g2000cwa.goo glegroups.com.. .[color=blue]
                  >
                  > Howard wrote:[color=green]
                  >> "Protoman" <Protoman2050@g mail.com> wrote in message
                  >>[color=darkred]
                  >> > T operator()(cons t T& base, T exp)throw(invAr g<T>)
                  >> > {
                  >> > if(exp<0)
                  >> > 1/operator()(base ,exp);
                  >> > else if(base==0)
                  >> > throw invArg<T>(base) ;
                  >> > else
                  >> > {
                  >> > T ret=1;
                  >> > for(;exp--;)
                  >> > exp*=base;
                  >> > return ret;
                  >> > }
                  >> > }
                  >> >[/color]
                  >>
                  >> Pass a negative number as the exponent to that function. What happens?
                  >> It
                  >> calls operator() again, passing it the SAME values. Which means it
                  >> passes a
                  >> negative value for exp again. So then what happens...?
                  >>[/color]
                  >
                  > OK, this should work, but how do I get it to stop closing after I
                  > input?
                  >
                  > #include <iostream>
                  > #include <cstdlib>
                  > using namespace std;
                  >
                  > template<class T>
                  > class invArg
                  > {
                  > public:
                  > explicit invArg(const T& arg):inv(arg){}
                  > virtual void Write()const{co ut << inv << endl;}
                  > private:
                  > T inv;
                  > };
                  >
                  > template<class T>
                  > class Exp
                  > {
                  > public:
                  > T operator()(cons t T& base, T exp)throw(invAr g<T>)
                  > {
                  > if(exp<0)
                  > goto neg;
                  > else if(base==0)
                  > throw invArg<T>(base) ;
                  > else
                  > {
                  > T ret=1;
                  > for(;exp--;)
                  > ret*=base;
                  > return ret;
                  > }
                  > neg:
                  > {
                  > T ret=1;
                  > for(;exp--;)
                  > ret*=base;
                  > return 1/ret;
                  > }
                  > }
                  > };
                  >
                  > int main()
                  > {
                  > try
                  > {
                  > long double base,exp;
                  > cout << "Enter a base and an exponent: " << endl;
                  > cin >> base >> exp;
                  > cout << base <<"^" << exp << "=" << fixed << Exp<long
                  > double>()(base, exp) << endl;
                  > system("PAUSE") ;
                  > return 0;
                  > }
                  > catch(invArg<co nst long double>& inv)
                  > {
                  > inv.Write();
                  > }
                  > }
                  >
                  > Any suggestions? Thanks!!![/color]

                  Yes, I have suggestions:

                  1) Read the other posts. One of the responders tells you why your app is
                  closing.
                  2) Use your debugger. It will tell you two things: first, that your
                  solution above does not work properly, and second, what it's doing when it
                  closes.
                  3) Why have you used a goto call? That's rarely a good design choice. Why
                  not just a block of code right where you need it? Or better yet, why not do
                  it the way you were (sort of), but pass the correct values when exp is
                  negative?
                  4) Do something about the editor or newsreader you're using: without
                  indentation, this is very hard to read.
                  5) What data types is this supposed to operate on? Consider especially what
                  it means to call the operator with a negative exponent when your type is
                  integral. If you only need to handle double (and/or float) do you really
                  need a template for this class? Seems like just handling the double type
                  with a function would work, without templates at all.
                  6) There's already a function called pow which handles raising to a power,
                  so why rewrite it?

                  -Howard



                  Comment

                  • Protoman

                    #10
                    Re: Problem with Exponent program


                    int2str@gmail.c om wrote:[color=blue]
                    > If you really have to do this (I'm sure your teacher would be ok
                    > without it), just to a getline( cin, temp); or so...[/color]

                    This is not homework, it's a hobby. And does pow handle negative
                    exponents?

                    Comment

                    • int2str@gmail.com

                      #11
                      Re: Problem with Exponent program


                      Protoman wrote:[color=blue]
                      > int2str@gmail.c om wrote:[color=green]
                      > > If you really have to do this (I'm sure your teacher would be ok
                      > > without it), just to a getline( cin, temp); or so...[/color]
                      >
                      > This is not homework, it's a hobby. And does pow handle negative
                      > exponents?[/color]

                      If it's a hobby I seriously suggest a good C++ book like "Accelerate d
                      C++". And a few good books on general programming.

                      Yes, pow() handles negative exponents as well as fractions as exponent.

                      Cheers,
                      Andre

                      Comment

                      • Protoman

                        #12
                        Re: Problem with Exponent program

                        Good. I'll use that. No sense in reinventing the square wheel.

                        Comment

                        Working...