开发者

Implementing Operator Overloading with Logarithms in C++

I'm having some issues with implementing a logarithm class with operator overloading in C++.

My first goal is how I would implement the changeBase method, I've been ha开发者_运维问答ving a tough time wrapping my head around it.

I have tried to understand the math behind changing the base of a logarithm, but i haven't been able to. Can someone please explain it to me?

My second goal is to be able to perform an operation where the left operand is a double and the right operand is a logarithm object.

Here's a snippet of my log class:

// coefficient: double
// base: unsigned int
// result: double
class _log {

 double coefficient, result;
 unsigned int base;

public:

 _log() {
  base = 10;
  coefficient = 0.0;
  result = 0.0;
 }
 _log operator+ ( const double b ) const;
 _log operator* ( const double b ) const;
 _log operator- ( const double b ) const;
 _log operator/ ( const double b ) const;
 _log operator<< ( const _log &b );

 double getValue() const;

 bool changeBase( unsigned int base );
};

You guys are awesome, thank you for your time.


My second goal is to be able to perform an operation where the left operand is a double and the right operand is a logarithm object.

To do this, you need to declare the operator as a non-member function at namespace scope (i.e., not in the definition of _log), e.g.,

_log operator+(const double a, const _log& b);

If you need access to the private members of _log, you can declare it as a friend inside the definition of _log:

friend _log operator+(const double a, const _log& b);

Note that names starting with an underscore (e.g., _log) are reserved to the implementation in the global namespace; if the underscore is followed by a capital letter or another underscore, it is reserved everywhere. It would be a good idea to choose a different class name.


A few things

  1. Using an _ in the front of your class is a Very Bad Idea (tm). From the c++ standard:

17.4.3.2.1 Global names [lib.global.names] Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.
  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.165

165) Such names are also reserved in namespace ::std (17.4.3.1).

  1. I'm guessing that you used _log instead of log due to the clash with log() in cmath. It is a Very Bad Idea to keep your own classes in the standard namespace for this very reason. Maybe the next version of the standard will provide a _log or Logarithm class? Wrap your own class in namespace somename {} and reference it by using somename::Logarithm()

  2. As others have mentioned already You need to declare your operator overloading as friend. Instead of what you have

    log operator+ ( const double b ) const;

    change it to

    friend log operator+(const double d, const log& l);
    

    and define the function in the namespace scope.

  3. Here is the math for the change of base formula

    Implementing Operator Overloading with Logarithms in C++

  4. Coefficient in math means the part that is being multiplied by the log. So if you had A log_b(x) = y

    A is the coefficient, B is the base, and Y is the result (or some other names)


A few ideas:

  1. Don't name with a leading underscore. Such identifiers are radioactive in C and C++.
  2. Define operations between logarithms before operations with floats.
  3. Combine #2 with James' suggestion:

    friend logarithm operator+( const logarithm &l, const logarithm &r );
    
  4. Define a conversion constructor to generate a logarithm from a float:

    logarithm::logarithm( double f );
    

    Now C++ will convert the double to a logarithm in either 1.0 + my_log or my_log + 1.0.

  5. Implement natural logarithms in your class. Don't bother with base.
  6. Define base conversion in terms of a function:

    double alternate_base( double base ) const;
    

    Base conversion is simply dividing the logarithm by the natural log of the alternate base. It is probably most convenient to return the integer and fractional parts together in a single double.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜