FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Operator overloading

 
Post new topic   Reply to topic     Forum Index -> Tutorials
View previous topic :: View next topic  
Author Message
DonAman



Joined: 27 Nov 2011
Posts: 4

PostPosted: Thu Jan 26, 2012 7:43 am    Post subject: Operator overloading Reply with quote

Hi,

Here is a short tutorial about operator overloading in D. Simply put, it's an example of implementation of a class of rational numbers. The code contains basic examples of binary and unary operator overloading. Overloading comparison operators is quite simple in D, since one single method handles them all!

Code:
/*
  rational.d
  Implements rational numbers made of a numerator and a denominator, with some basic operations
  Basic operations have to be overloaded, the same goes for comparison operators
*/

import std.stdio;
import std.string: format;
import std.math:abs;

class Rational {
private:
   long  _num;
   ulong _den;
   
public:
   this() {
      _num = 0;
      _den = 1;
   }
   
   this(long num,ulong den) {
      if(den == 0) {
    throw new Exception("trying to create a rational number with a denominator equal to zero.");
      }
      int n = gcd(num,den);
      _num    = num/n;
      _den    = den/n;
   }
   
   this(Rational d) {
      _num = d._num;
      _den = d._den;
   }
   
   static long min(long a,long b) {
      return a<b ? a : b;
   }
   
   static long max(long a,long b) {
      return a<b ? b: a;
   }
   
   static long gcd(long a,long b) {
      if(a<0 || a<b || b<0) {
    return gcd(max(abs(a),abs(b)),min(abs(a),abs(b)));
      }
      return (a%b!=0)? gcd(b,a%b) : b;
   }
   
   void display() {
      (_den==1)?
    writefln("%d",_num):
    writefln("(" ~ format(_num) ~ "/" ~ format(_den) ~ ")");
   }
   
   Rational inverse() {
      if(_num == 0) {
    throw new Exception("0 is not invertible");
      }
      return (_num > 0) ?
    new Rational(_den,_num):
    new Rational(-(_den),-(_num));
   }
   
   static Rational maxr(ref Rational q1,ref Rational q2) {
      return q1>q2? q1: q2; // ok because comparison operators are overloaded
   }
   
   /* Binary operator overloading */
   Rational opAdd(Rational q) {
      return new Rational(_num*q._den+_den*q._num,_den*q._den);
   }
   
   /* Adding floating numbers is slightly more difficult */
   Rational opAdd(long d) {
      return new Rational(_num+_den*d,_den);
   }
   
   Rational opMul(Rational q) {
      return new Rational(_num*q._num,_den*q._den);
   }
   
   Rational opSub(Rational q) {
      return new Rational(_num*q._den-_den*q._num,_den*q._den);
   }
   
   Rational opDiv(Rational q) {
      if (q._num == 0) {
    throw new Exception("trying to divide by a rational number equal to zero.");
      }
      return this*q.inverse();
   }
   
   void opAddAssign(Rational q) {
     
      _num = (_num*q._den+_den*q._num);
      _den = (_den*q._den);
      /* conversion into an irreductible fraction */
      ulong gcd = gcd((_num <0) ? (-_num) : (_num),_den);
      if(gcd != 1) {
    _num /= gcd;
    _den /= gcd;
      }
   }
   
   /* Unary operator overloading */
   Rational opNeg() {
      return new Rational(-(_num),_den);
   }
   
   /* Overloading comparison operators */
   int opCmp(Rational other) {
      return _num*other._den - other._num*_den;
   }
}
   
void main() {
   Rational r = new Rational();
   writefln("Let's start with r = 0.");
   r = r + 1;
   writef("r = ");
   r.display();
   /* r = 1 */
   r = r*new Rational(2,1);
   writef("\t*2 = ");
   r.display();
   /* r = 2 */
   r = (new Rational(1,3))*r;
   writef("\t\t*1/3 = ");
   r.display();
   /* r = 2/3 */
   r = r/(new Rational(3,1));
   writef("\t\t\t/3 = ");
   r.display();
   /* r = 2/9 */
   r = r + new Rational(1,3);
   writef("\t\t\t\t+1/3 = ");
   r.display();
   /* r = 5/9 */
   r += new Rational(1,3);
   writef("r += 1/3 -> r = ");
   r.display();
   /* r = 8/9 */
   r = r - new Rational(1,2);
   writef("\t\t-1/2 = ");
   r.display();
   /* r = 7/18 */
   r = -r;
   writef("r = -r -> r = ");
   r.display();
   /* r = -7/18 */
   Rational x = new Rational(-5,18);
   r = Rational.maxr(r,x);
   writef("max(r,-5/18) = ");
   r.display();
   /* r = -5/18 */
}


(Compiled with dmd 1.071)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Tutorials All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group