Implementing operator overloading with logarithms in C ++
I am having some trouble implementing a logarithm class with operator overloading in C ++.
My first goal is how to implement the method changeBase
, I had a hard time wrapping my head around it.
I tried to understand the math behind changing the base of the logarithm, but I couldn't. Can someone explain this to me?
My second goal is to perform an operation in which the left operand is double
and the right operand is a logarithmic object.
Here is 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, thanks for your time.
a source to share
A few things
- Using _ in front of your class is a very bad idea (tm). From the C ++ standard:
17.4.3.2.1 Global names [lib.global.names] Some sets of function names and signatures are always reserved for implementation:
- Every name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter (2.11) is reserved for any use.
- Each name that begins with an underscore is implementation reserved for use as a name in the global namespace. 165
165). Such names are also reserved in the :: std namespace (17.4.3.1).
-
I am assuming you were using _log instead of log due to collision 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 refer to it withsomename::Logarithm()
-
As mentioned, you need to declare your operator overload as a 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 namespace scope.
-
Here is the math for changing the basic formula

-
Coefficient in mathematics means the part that is multiplied by the log. So if you were A log_b (x) = y
A is the coefficient, B is the base, and Y is the result (or some other names)
a source to share
My second goal is to perform an operation where the left operand is a double and the right operand is a logarithmic object.
To do this, you need to declare the operator as a non-member function in the namespace scope (i.e. not in the definition _log
), for example
_log operator+(const double a, const _log& b);
If you need access to private members _log
, you can declare it as a friend in the definition _log
:
friend _log operator+(const double a, const _log& b);
Note that names beginning with an underscore character (for example _log
) are reserved for implementation in the global namespace; if the underscore is followed by a capital letter or other underscore, it is reserved everywhere. It would be nice to choose a different class name.
a source to share
Some ideas:
- Don't call it a leading underscore. Such identifiers are radioactive in C and C ++.
- Define operations between logarithms before operations with floats.
-
Combine # 2 with James's suggestion:
friend logarithm operator+( const logarithm &l, const logarithm &r );
-
Define a conversion constructor to generate a
logarithm
from float:logarithm::logarithm( double f );
Now C ++ converts
double
tologarithm
either to1.0 + my_log
ormy_log + 1.0
. - Introduce natural logarithms to your class. Don't worry
base
. -
Define a basic conversion in terms of a function:
double alternate_base( double base ) const;
The base transform simply divides
logarithm
into the natural log of the alternative base. It is probably most convenient to return the integer and fractional parts together in onedouble
.
a source to share
