Errors implementing class functions "no match for operator"

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

44 Replies - 1015 Views - Last Post: 25 September 2013 - 10:54 PM Rate Topic: -----

#1 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 104
  • Joined: 26-June 12

Errors implementing class functions "no match for operator"

Posted 23 September 2013 - 10:36 PM

natural.h
#ifndef NATURAL_H
#define NATURAL_H

#include <iostream>
#include <utility>

// The natural numbers are the non-negative integers.
// This class allows for the manipulation of natural numbers of
// arbitarily large size.

class Natural
{
public:
  Natural();
  //   Natural k;
  //post:  k == 0

  Natural (unsigned i);
  //   Natural k = i;
  //post:  k == i

  Natural (const Natural&);
  ~Natural();
  Natural& operator= (const Natural&);

  Natural& operator+= (const Natural& i);
  Natural& operator-= (const Natural& i);
  
  Natural& operator++ ();
  Natural operator++ (int);
  Natural& operator-- ();
  Natural operator-- (int);

private:

  // Implemented as a linked list of digits, each digit should
  // be a number between 0 and 9, inclusive.
  struct DigitList {
    int data;
    DigitList* prev;
    DigitList* next;

    DigitList (unsigned d, DigitList* prv = 0, DigitList* nxt = 0)
      : data(d), prev(prv), next(nxt)
      {}
  };
  unsigned nDigits;
  DigitList* leadingDigit;
  DigitList* trailingDigit;


  void clear();
  // Empty the list

  void normalize();
  // Between operations (though not necessarily during the implementation
  // of an operation), all Natural numbers should be in "normal form" 
  //   - each digit should be between 0 and 9, inclusive
  //   - the leading digit should be non-zero, unless the number itself is
  //     zero, in which case it will have a single zero digit
  // This function scans the number, correcting any deviations from
  // normal form.

  // Internal operations for list manipulation
  void addLeadingZero();
  // adds a 0 digit to the front of the number

  void timesTen();
  // adds a 0 digit to the end of the number, effectively multiplying it by 10

  void divTen();
  // removes the trailing digit of a number, effectively dividing it by 10

  friend Natural operator+ (const Natural& i, const Natural& j);
  friend Natural operator- (const Natural& i, const Natural& j);
  friend Natural operator* (const Natural& i, const Natural& j);
  friend Natural operator/ (const Natural& i, const Natural& j);
  
  friend std::ostream&  operator<< (std::ostream& out, const Natural& k);


  // Utility functions

  void multiplyByDigit (unsigned i);
  //pre: 0 <= i < 10
  //   Natural k = k0;  k.multiplyBy(i);
  //post: k == k0 * i

  void divideBy2 ();  
  //   Natural k = k0;  j = k.divideBy2();
  //post: k0 == 2*k  || k0 = 2*k + 1

  void subtract1 ();
  //   Natural k = k0; k.subtract1();
  //Post:  k0 == k + 1

};


Natural operator+ (const Natural& i, const Natural& j);
Natural operator- (const Natural& i, const Natural& j);
Natural operator* (const Natural& i, const Natural& j);
Natural operator/ (const Natural& i, const Natural& j);

using namespace std::rel_ops;
  
std::ostream&  operator<< (std::ostream& out, const Natural& k);


#endif



natural1.cpp
#include "natural.h"

using namespace std;

// The natural numbers are the non-negative integers.
// This class allows for the manipulation of natural numbers of
// arbitarily large size.

Natural::Natural()
//   Natural k;
//post:  k == 0
{
  nDigits = 1;
  leadingDigit = trailingDigit = new DigitList(0);
}

Natural::Natural (unsigned i)
//   Natural k = i;
//post:  k == i
{
  nDigits = 1;
  leadingDigit = trailingDigit = new DigitList(i);
  normalize();
}



Natural& Natural::operator++ ()
{
  ++(trailingDigit->data);
  normalize();
  return *this;
}

Natural Natural::operator++ (int)
{
  Natural original = *this;
  ++(trailingDigit->data);
  normalize();
  return original;
}

Natural& Natural::operator-- ()
{
  --(trailingDigit->data);
  normalize();
  return *this;
}

Natural Natural::operator-- (int)
{
  Natural original = *this;
  --(trailingDigit->data);
  normalize();
  return original;
}



void Natural::normalize()
// Between operations (though not necessarily during the implementation
// of an operation), all Natural numbers should be in "normal form" 
//   - each digit should be between 0 and 9, inclusive
//   - the leading digit should be non-zero, unless the number itself is
//     zero, in which case it will have a single zero digit
// This function scans the number, correcting any deviations from
// normal form.
{
  DigitList* d = trailingDigit;
  int carry = 0;
  while (d != 0)
    {
      d->data += carry;
      carry = 0;
      if (d->data >= 10)
	{
	  carry = d->data / 10;
	  d->data = d->data % 10;
	}
      else if (d->data < 0)
	{
	  carry = 1 + (-(d->data+1)) / 10;
	  d->data = (carry * 10 + d->data);
	  carry = -carry;
	}
      d = d->prev;
    }
  while (carry > 0)
    {
      addLeadingZero();
      leadingDigit->data = carry % 10;
      carry = carry / 10;
    }
  d = leadingDigit;
  while (d != 0 && d->data == 0 && d != trailingDigit) 
    {
      leadingDigit = d->next;
      delete d;
      leadingDigit->prev = 0;
      --nDigits;
      d = leadingDigit;
    }
  if (carry < 0)
    {
      clear();
      nDigits = 1;
      leadingDigit = trailingDigit = new DigitList(0);
    }
}


// Internal operations for list manipulation

void Natural::clear()
{
  for (DigitList* d = leadingDigit; d != NULL;)
      {
	DigitList* nxt = d->next;
	delete d;
	d = nxt;
      }
  nDigits = 0;
}



void Natural::addLeadingZero()
// adds a 0 digit to the front of the number
{
  DigitList* d = new DigitList(0, 0, leadingDigit);
  leadingDigit->prev = d;
  leadingDigit = d;
  ++nDigits;
}



void Natural::timesTen()
// adds a 0 digit to the end of the number, effectively 
//  multiplying it by 10
{
  DigitList* d = new DigitList(0, trailingDigit, 0);
  trailingDigit->next = d;
  trailingDigit = d;
  ++nDigits;
}


void Natural::divTen()
// Removes the trailing digit of the number, effectively 
//  dividing it by 10
{
  DigitList* d = trailingDigit;
  trailingDigit = d->prev;
  if (trailingDigit == 0)
    leadingDigit = 0;
  else
    trailingDigit->next = 0;
  delete d;
  --nDigits;
}


Natural operator+ (const Natural& i, const Natural& j)
{
  Natural k = i;
  k += j;
  return k;
}


Natural operator* (const Natural& i, const Natural& j)
{
  Natural sum;
  Natural ii = i;
  for (Natural::DigitList* d = j.trailingDigit; d != 0; d = d->prev)
    {
      Natural m = ii;
      m.multiplyByDigit(d->data);
      sum += m;
      ii.timesTen();
    }
  return sum;
}


Natural operator/ (const Natural& i, const Natural& j)
{
  Natural quotient;
  Natural divisor = j;
  Natural remainder = i;

  int nShifts = 0;

  while (divisor.nDigits < remainder.nDigits)
    {
      divisor.timesTen();
      ++nShifts;
    }

  for (int i = 0; i <= nShifts; ++i)
    {
      int digit = 0;
      while (divisor <= remainder)
	{
	  remainder = remainder - divisor;
	  ++digit;
	}
      if (i > 0)
	quotient.timesTen();
      quotient.trailingDigit->data = digit;
      divisor.divTen();
    }
  quotient.normalize();
  return quotient;
}
  


ostream&  operator<< (ostream& out, const Natural& k)
{
  for (Natural::DigitList* d = k.leadingDigit; d != 0; d = d->next)
    out << d->data;
  return out;
}


// Utility functions

void Natural::multiplyByDigit (unsigned i)
//pre: 0 <= i < 10
//   Natural k = k0;  k.multiplyBy(i);
//post: k == k0 * i
{
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    d->data *= i;
  normalize();
}


void Natural::divideBy2 ()
//   Natural k = k0;  j = k.divideBy2();
//post: k0 == 2*k  || k0 = 2*k + 1
{
  int carry = 0;
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    {
      int k = 10 * carry + d->data;
      d->data = k / 2;
      carry = k % 2;
    }
  normalize();
}



natural2.cpp
#include "natural.h"

using namespace std;


// Insert your own function bodies in this file

Natural::Natural (const Natural& i)
{
    leadingDigit = trailingDigit = new DigitList (nDigits);
    for (unsigned j = 0; j < nDigits; ++j) 
    leadingDigit[j] = i.leadingDigit[j];
}

Natural::~Natural()
{
    clear();
}

Natural& Natural::operator= (const Natural& i)
{
  if (this != &i)
      {
          clear();
          nDigits = i.nDigits;
          for (unsigned j = 0; j <= nDigits; ++j)
            leadingDigit[j] = i.leadingDigit[j]
      }
    return *this;
}

void Natural::subtract1 ()
//   Natural k = k0; k.subtract1();
//Post:  k0 == k + 1
{
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    d->data -= 1;
  normalize();
}

Natural operator- (const Natural& i, const Natural& j)
{
  Natural k = i;
  k -= j;
  return k;
}



The following errors received when compiling natural2.cpp
17 undefined reference to `Natural::clear()'
24 undefined reference to `Natural::clear()'
38 undefined reference to `Natural::normalize()'
44 undefined reference to `Natural::operator-=(Natural const&)'
18 undefined reference to `WinMain'
Any help pointing me in the right direction is appreciated.

Is This A Good Question/Topic? 0
  • +

Replies To: Errors implementing class functions "no match for operator"

#2 Draps  Icon User is offline

  • D.I.C Head

Reputation: 33
  • View blog
  • Posts: 103
  • Joined: 20-November 10

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 12:15 AM

You never define those methods in your natural2 file.

yet you try to use them...
Was This Post Helpful? 1
  • +
  • -

#3 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 104
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 08:01 AM

Ah, I see, so I need to include Natural1.cpp
Was This Post Helpful? 0
  • +
  • -

#4 jimblumberg  Icon User is offline

  • member icon


Reputation: 3845
  • View blog
  • Posts: 11,749
  • Joined: 25-December 09

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 08:08 AM

Quote

Ah, I see, so I need to include Natural1.cpp

No! You need to add Natural1.cpp to your project or compile line. You rarely if ever will include a .cpp file.

Jim
Was This Post Helpful? 1
  • +
  • -

#5 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 104
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 09:58 AM

Sorry, as soon as I posted that I realized the issue (it's been a long week). I have made some strides in the correct direction (I think). Here's what I currently have.

natural.h

#ifndef NATURAL_H
#define NATURAL_H

#include <iostream>
#include <utility>

using namespace std;

// The natural numbers are the non-negative integers.
// This class allows for the manipulation of natural numbers of
// arbitarily large size.

class Natural
{
public:
  Natural();
  //   Natural k;
  //post:  k == 0

  Natural (unsigned i);
  //   Natural k = i;
  //post:  k == i

  Natural (const Natural&);
  ~Natural();
  Natural& operator= (const Natural&);

  Natural& operator+= (const Natural& i);
  Natural& operator-= (const Natural& i);
  
  Natural& operator++ ();
  Natural operator++ (int);
  Natural& operator-- ();
  Natural operator-- (int);

private:

  // Implemented as a linked list of digits, each digit should
  // be a number between 0 and 9, inclusive.
  struct DigitList {
    int data;
    DigitList* prev;
    DigitList* next;

    DigitList (unsigned d, DigitList* prv = 0, DigitList* nxt = 0)
      : data(d), prev(prv), next(nxt)
      {}
  };
  unsigned nDigits;
  DigitList* leadingDigit;
  DigitList* trailingDigit;


  void clear();
  // Empty the list

  void normalize();
  // Between operations (though not necessarily during the implementation
  // of an operation), all Natural numbers should be in "normal form" 
  //   - each digit should be between 0 and 9, inclusive
  //   - the leading digit should be non-zero, unless the number itself is
  //     zero, in which case it will have a single zero digit
  // This function scans the number, correcting any deviations from
  // normal form.

  // Internal operations for list manipulation
  void addLeadingZero();
  // adds a 0 digit to the front of the number

  void timesTen();
  // adds a 0 digit to the end of the number, effectively multiplying it by 10

  void divTen();
  // removes the trailing digit of a number, effectively dividing it by 10

  friend Natural operator+ (const Natural& i, const Natural& j);
  friend Natural operator- (const Natural& i, const Natural& j);
  friend Natural operator* (const Natural& i, const Natural& j);
  friend Natural operator/ (const Natural& i, const Natural& j);
  
  friend std::ostream&  operator<< (std::ostream& out, const Natural& k);


  // Utility functions

  void multiplyByDigit (unsigned i);
  //pre: 0 <= i < 10
  //   Natural k = k0;  k.multiplyBy(i);
  //post: k == k0 * i

  void divideBy2 ();  
  //   Natural k = k0;  j = k.divideBy2();
  //post: k0 == 2*k  || k0 = 2*k + 1

  void subtract1 ();
  //   Natural k = k0; k.subtract1();
  //Post:  k0 == k + 1

};


Natural operator+ (const Natural& i, const Natural& j);
Natural operator- (const Natural& i, const Natural& j);
Natural operator* (const Natural& i, const Natural& j);
Natural operator/ (const Natural& i, const Natural& j);
Natural operator== (const Natural& i, const Natural& j);
Natural operator< (const Natural& i, const Natural& j);
Natural operator!= (const Natural& i, const Natural& j);
Natural operator> (const Natural& i, const Natural& j);
Natural operator<= (const Natural& i, const Natural& j);
Natural operator>= (const Natural& i, const Natural& j);

using namespace std::rel_ops;

std::ostream&  operator<< (std::ostream& out, const Natural& k);


#endif



natural1.cpp
#include "natural.h"

using namespace std;

// The natural numbers are the non-negative integers.
// This class allows for the manipulation of natural numbers of
// arbitarily large size.

Natural::Natural()
//   Natural k;
//post:  k == 0
{
  nDigits = 1;
  leadingDigit = trailingDigit = new DigitList(0);
}

Natural::Natural (unsigned i)
//   Natural k = i;
//post:  k == i
{
  nDigits = 1;
  leadingDigit = trailingDigit = new DigitList(i);
  normalize();
}



Natural& Natural::operator++ ()
{
  ++(trailingDigit->data);
  normalize();
  return *this;
}

Natural Natural::operator++ (int)
{
  Natural original = *this;
  ++(trailingDigit->data);
  normalize();
  return original;
}

Natural& Natural::operator-- ()
{
  --(trailingDigit->data);
  normalize();
  return *this;
}

Natural Natural::operator-- (int)
{
  Natural original = *this;
  --(trailingDigit->data);
  normalize();
  return original;
}



void Natural::normalize()
// Between operations (though not necessarily during the implementation
// of an operation), all Natural numbers should be in "normal form" 
//   - each digit should be between 0 and 9, inclusive
//   - the leading digit should be non-zero, unless the number itself is
//     zero, in which case it will have a single zero digit
// This function scans the number, correcting any deviations from
// normal form.
{
  DigitList* d = trailingDigit;
  int carry = 0;
  while (d != 0)
    {
      d->data += carry;
      carry = 0;
      if (d->data >= 10)
	{
	  carry = d->data / 10;
	  d->data = d->data % 10;
	}
      else if (d->data < 0)
	{
	  carry = 1 + (-(d->data+1)) / 10;
	  d->data = (carry * 10 + d->data);
	  carry = -carry;
	}
      d = d->prev;
    }
  while (carry > 0)
    {
      addLeadingZero();
      leadingDigit->data = carry % 10;
      carry = carry / 10;
    }
  d = leadingDigit;
  while (d != 0 && d->data == 0 && d != trailingDigit) 
    {
      leadingDigit = d->next;
      delete d;
      leadingDigit->prev = 0;
      --nDigits;
      d = leadingDigit;
    }
  if (carry < 0)
    {
      clear();
      nDigits = 1;
      leadingDigit = trailingDigit = new DigitList(0);
    }
}


// Internal operations for list manipulation

void Natural::clear()
{
  for (DigitList* d = leadingDigit; d != NULL;)
      {
	DigitList* nxt = d->next;
	delete d;
	d = nxt;
      }
  nDigits = 0;
}



void Natural::addLeadingZero()
// adds a 0 digit to the front of the number
{
  DigitList* d = new DigitList(0, 0, leadingDigit);
  leadingDigit->prev = d;
  leadingDigit = d;
  ++nDigits;
}



void Natural::timesTen()
// adds a 0 digit to the end of the number, effectively 
//  multiplying it by 10
{
  DigitList* d = new DigitList(0, trailingDigit, 0);
  trailingDigit->next = d;
  trailingDigit = d;
  ++nDigits;
}


void Natural::divTen()
// Removes the trailing digit of the number, effectively 
//  dividing it by 10
{
  DigitList* d = trailingDigit;
  trailingDigit = d->prev;
  if (trailingDigit == 0)
    leadingDigit = 0;
  else
    trailingDigit->next = 0;
  delete d;
  --nDigits;
}


Natural operator+ (const Natural& i, const Natural& j)
{
  Natural k = i;
  k += j;
  return k;
}


Natural operator* (const Natural& i, const Natural& j)
{
  Natural sum;
  Natural ii = i;
  for (Natural::DigitList* d = j.trailingDigit; d != 0; d = d->prev)
    {
      Natural m = ii;
      m.multiplyByDigit(d->data);
      sum += m;
      ii.timesTen();
    }
  return sum;
}


Natural operator/ (const Natural& i, const Natural& j)
{
  Natural quotient;
  Natural divisor = j;
  Natural remainder = i;

  int nShifts = 0;

  while (divisor.nDigits < remainder.nDigits)
    {
      divisor.timesTen();
      ++nShifts;
    }

  for (int i = 0; i <= nShifts; ++i)
    {
      int digit = 0;
      while (divisor <= remainder)
	{
	  remainder = remainder - divisor;
	  ++digit;
	}
      if (i > 0)
	quotient.timesTen();
      quotient.trailingDigit->data = digit;
      divisor.divTen();
    }
  quotient.normalize();
  return quotient;
}
  


ostream&  operator<< (ostream& out, const Natural& k)
{
  for (Natural::DigitList* d = k.leadingDigit; d != 0; d = d->next)
    out << d->data;
  return out;
}


// Utility functions

void Natural::multiplyByDigit (unsigned i)
//pre: 0 <= i < 10
//   Natural k = k0;  k.multiplyBy(i);
//post: k == k0 * i
{
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    d->data *= i;
  normalize();
}


void Natural::divideBy2 ()
//   Natural k = k0;  j = k.divideBy2();
//post: k0 == 2*k  || k0 = 2*k + 1
{
  int carry = 0;
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    {
      int k = 10 * carry + d->data;
      d->data = k / 2;
      carry = k % 2;
    }
  normalize();
}



natural2.cpp
#include "natural.h"


using namespace std;


// Insert your own function bodies in this file

Natural::Natural (const Natural& i)
{
    leadingDigit = trailingDigit = new DigitList (nDigits);
    for (unsigned j = 0; j < nDigits; ++j) 
    leadingDigit[j] = i.leadingDigit[j];
}

Natural::~Natural()
{
    clear();
}

Natural& Natural::operator= (const Natural& i)
{
  if (this != &i)
      {
          clear();
          nDigits = i.nDigits;
          for (unsigned j = 0; j <= nDigits; ++j)
            leadingDigit[j] = i.leadingDigit[j];
      }
    return *this;
}

void Natural::subtract1 ()
//   Natural k = k0; k.subtract1();
//Post:  k0 == k + 1
{
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    d->data -= 1;
  normalize();
}

Natural operator- (const Natural& i, const Natural& j)
{
  Natural k = i;
  k -= j;
  return k;
}



I have gotten natural2 to compile, when I try natural1, I get the following error:
$ g++ -c natural1.cpp
natural1.cpp: In function `Natural operator/(const Natural&, const Natural&)':
natural1.cpp:204: error: could not convert `operator<=(const Natural&, const Natural&)(((const Natural&)((const Natural*)(&remainder))))' to `bool'
Was This Post Helpful? 0
  • +
  • -

#6 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 630
  • View blog
  • Posts: 2,107
  • Joined: 31-December 10

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 10:15 AM

You declare the relational operators for the Natural class in natural.h, but you don't define them anywhere. That's the reason for the error because you try to use the relational operators without defining them.
Was This Post Helpful? 1
  • +
  • -

#7 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 104
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 02:57 PM

I believe I've finally made some headway. My apologies for my earlier code. I'm under the gun on this, and a few other things and wasn't thinking straight. I've gotten my ducks into a row, but am now getting a segmentation fault. As always, any direction is much appreciated.

natural.h
#ifndef NATURAL_H
#define NATURAL_H

#include <iostream>
#include <utility>
#include <cmath>

using namespace std;

// The natural numbers are the non-negative integers.
// This class allows for the manipulation of natural numbers of
// arbitarily large size.

class Natural
{
public:
  Natural();
  //   Natural k;
  //post:  k == 0

  Natural (unsigned i);
  //   Natural k = i;
  //post:  k == i

  Natural (const Natural&);
  ~Natural();
  Natural& operator= (const Natural&);

  Natural& operator+= (const Natural& i);
  Natural& operator-= (const Natural& i);
  
  Natural& operator++ ();
  Natural operator++ (int);
  Natural& operator-- ();
  Natural operator-- (int);

private:

  // Implemented as a linked list of digits, each digit should
  // be a number between 0 and 9, inclusive.
  struct DigitList {
    int data;
    DigitList* prev;
    DigitList* next;

    DigitList (unsigned d, DigitList* prv = 0, DigitList* nxt = 0)
      : data(d), prev(prv), next(nxt)
      {}
  };
  unsigned nDigits;
  DigitList* leadingDigit;
  DigitList* trailingDigit;


  void clear();
  // Empty the list

  void normalize();
  // Between operations (though not necessarily during the implementation
  // of an operation), all Natural numbers should be in "normal form" 
  //   - each digit should be between 0 and 9, inclusive
  //   - the leading digit should be non-zero, unless the number itself is
  //     zero, in which case it will have a single zero digit
  // This function scans the number, correcting any deviations from
  // normal form.

  // Internal operations for list manipulation
  void addLeadingZero();
  // adds a 0 digit to the front of the number

  void timesTen();
  // adds a 0 digit to the end of the number, effectively multiplying it by 10

  void divTen();
  // removes the trailing digit of a number, effectively dividing it by 10

  friend Natural operator+ (const Natural& i, const Natural& j);
  friend Natural operator- (const Natural& i, const Natural& j);
  friend Natural operator* (const Natural& i, const Natural& j);
  friend Natural operator/ (const Natural& i, const Natural& j);
   
  friend std::ostream&  operator<< (std::ostream& out, const Natural& k);


  // Utility functions

  void multiplyByDigit (unsigned i);
  //pre: 0 <= i < 10
  //   Natural k = k0;  k.multiplyBy(i);
  //post: k == k0 * i

  void divideBy2 ();  
  //   Natural k = k0;  j = k.divideBy2();
  //post: k0 == 2*k  || k0 = 2*k + 1

  void subtract1 ();
  //   Natural k = k0; k.subtract1();
  //Post:  k0 == k + 1

};


Natural operator+ (const Natural& i, const Natural& j);
Natural operator- (const Natural& i, const Natural& j);
Natural operator* (const Natural& i, const Natural& j);
Natural operator/ (const Natural& i, const Natural& j);
bool operator== (const Natural& i, const Natural& j);
bool operator< (const Natural& i, const Natural& j);

using namespace std::rel_ops;

std::ostream&  operator<< (std::ostream& out, const Natural& k);


#endif




natural1.cpp
#include "natural.h"

using namespace std;

// The natural numbers are the non-negative integers.
// This class allows for the manipulation of natural numbers of
// arbitarily large size.

Natural::Natural()
//   Natural k;
//post:  k == 0
{
  nDigits = 1;
  leadingDigit = trailingDigit = new DigitList(0);
}

Natural::Natural (unsigned i)
//   Natural k = i;
//post:  k == i
{
  nDigits = 1;
  leadingDigit = trailingDigit = new DigitList(i);
  normalize();
}



Natural& Natural::operator++ ()
{
  ++(trailingDigit->data);
  normalize();
  return *this;
}

Natural Natural::operator++ (int)
{
  Natural original = *this;
  ++(trailingDigit->data);
  normalize();
  return original;
}

Natural& Natural::operator-- ()
{
  --(trailingDigit->data);
  normalize();
  return *this;
}

Natural Natural::operator-- (int)
{
  Natural original = *this;
  --(trailingDigit->data);
  normalize();
  return original;
}



void Natural::normalize()
// Between operations (though not necessarily during the implementation
// of an operation), all Natural numbers should be in "normal form" 
//   - each digit should be between 0 and 9, inclusive
//   - the leading digit should be non-zero, unless the number itself is
//     zero, in which case it will have a single zero digit
// This function scans the number, correcting any deviations from
// normal form.
{
  DigitList* d = trailingDigit;
  int carry = 0;
  while (d != 0)
    {
      d->data += carry;
      carry = 0;
      if (d->data >= 10)
	{
	  carry = d->data / 10;
	  d->data = d->data % 10;
	}
      else if (d->data < 0)
	{
	  carry = 1 + (-(d->data+1)) / 10;
	  d->data = (carry * 10 + d->data);
	  carry = -carry;
	}
      d = d->prev;
    }
  while (carry > 0)
    {
      addLeadingZero();
      leadingDigit->data = carry % 10;
      carry = carry / 10;
    }
  d = leadingDigit;
  while (d != 0 && d->data == 0 && d != trailingDigit) 
    {
      leadingDigit = d->next;
      delete d;
      leadingDigit->prev = 0;
      --nDigits;
      d = leadingDigit;
    }
  if (carry < 0)
    {
      clear();
      nDigits = 1;
      leadingDigit = trailingDigit = new DigitList(0);
    }
}


// Internal operations for list manipulation

void Natural::clear()
{
  for (DigitList* d = leadingDigit; d != NULL;)
      {
	DigitList* nxt = d->next;
	delete d;
	d = nxt;
      }
  nDigits = 0;
}



void Natural::addLeadingZero()
// adds a 0 digit to the front of the number
{
  DigitList* d = new DigitList(0, 0, leadingDigit);
  leadingDigit->prev = d;
  leadingDigit = d;
  ++nDigits;
}



void Natural::timesTen()
// adds a 0 digit to the end of the number, effectively 
//  multiplying it by 10
{
  DigitList* d = new DigitList(0, trailingDigit, 0);
  trailingDigit->next = d;
  trailingDigit = d;
  ++nDigits;
}


void Natural::divTen()
// Removes the trailing digit of the number, effectively 
//  dividing it by 10
{
  DigitList* d = trailingDigit;
  trailingDigit = d->prev;
  if (trailingDigit == 0)
    leadingDigit = 0;
  else
    trailingDigit->next = 0;
  delete d;
  --nDigits;
}


Natural operator+ (const Natural& i, const Natural& j)
{
  Natural k = i;
  k += j;
  return k;
}


Natural operator* (const Natural& i, const Natural& j)
{
  Natural sum;
  Natural ii = i;
  for (Natural::DigitList* d = j.trailingDigit; d != 0; d = d->prev)
    {
      Natural m = ii;
      m.multiplyByDigit(d->data);
      sum += m;
      ii.timesTen();
    }
  return sum;
}


Natural operator/ (const Natural& i, const Natural& j)
{
  Natural quotient;
  Natural divisor = j;
  Natural remainder = i;

  int nShifts = 0;

  while (divisor.nDigits < remainder.nDigits)
    {
      divisor.timesTen();
      ++nShifts;
    }

  for (int i = 0; i <= nShifts; ++i)
    {
      int digit = 0;
      while (divisor <= remainder)
	{
	  remainder = remainder - divisor;
	  ++digit;
	}
      if (i > 0)
	quotient.timesTen();
      quotient.trailingDigit->data = digit;
      divisor.divTen();
    }
  quotient.normalize();
  return quotient;
}
  


ostream&  operator<< (ostream& out, const Natural& k)
{
  for (Natural::DigitList* d = k.leadingDigit; d != 0; d = d->next)
    out << d->data;
  return out;
}


// Utility functions

void Natural::multiplyByDigit (unsigned i)
//pre: 0 <= i < 10
//   Natural k = k0;  k.multiplyBy(i);
//post: k == k0 * i
{
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    d->data *= i;
  normalize();
}


void Natural::divideBy2 ()
//   Natural k = k0;  j = k.divideBy2();
//post: k0 == 2*k  || k0 = 2*k + 1
{
  int carry = 0;
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    {
      int k = 10 * carry + d->data;
      d->data = k / 2;
      carry = k % 2;
    }
  normalize();
}




natural2.cpp
#include "natural.h"


using namespace std;


// Insert your own function bodies in this file

Natural::Natural (const Natural& i)
{
    leadingDigit = trailingDigit = new DigitList (nDigits);
    for (unsigned j = 0; j < nDigits; ++j) 
    leadingDigit[j] = i.leadingDigit[j];
}

Natural::~Natural()
{
    clear();
}

Natural& Natural::operator= (const Natural& i)
{
  if (this != &i)
      {
          clear();
          nDigits = i.nDigits;
          for (unsigned j = 0; j <= nDigits; ++j)
            leadingDigit[j] = i.leadingDigit[j];
      }
    return *this;
}


void Natural::subtract1 ()
//   Natural k = k0; k.subtract1();
//Post:  k0 == k + 1
{
  for (DigitList* d = leadingDigit; d != 0; d = d->next)
    d->data -= 1;
  normalize();
}

Natural operator- (const Natural& i, const Natural& j)
{
  Natural k = i;
  k -= j;
  return k;
}

bool operator== (const Natural& i, const Natural& j)
{
  return i == j;
}

bool operator< (const Natural& i, const Natural& j)
{
  return i < j;
}




odds.cpp

#include <iostream>
#include "natural.h"


using namespace std;



Natural factorial (const Natural& j)
{
  Natural k = 1;
  for (Natural i = 2; i <= j; ++i)
    {
      k = k * i;
    }
  return k;
}


int main (int argc, char** argv) 
{
  unsigned k, n;
  cout << "What is the largest number in the lottery? " << flush;
  cin >> n;
  cout << "\nHow many numbers in each drawing? " << flush;
  cin >> k;
  cout << "\n";

  // Additional output for debugging purposes
  //  (and to help in providing partial credit when grading)
  //  is activated by running the program with a -debug flag:
  //    lottery.exe -debug
  string debugFlag ((argc > 1) ? argv[1] : "");
  if (debugFlag == "-debug")
    {
      Natural x = n;
      
      // try doubling x 32 times to test addition:
      for (int i = 0; i < 32; i++)
	{
	  x = x + x;
	}
      cout << "Addition test: " << x << endl;

      // Subtraction
      Natural sub = x - n;
      cout << "Subtraction test: " << sub << endl;

      // Division
      Natural div = x / n;
      cout << "Division test: " << div << endl;


      // Multiplication test
      for (int i = 0; i < 8; i++)
	{
	  x = x * n;
	}
      cout << "Multiplication test: " << x << endl;


      // Check the equality and < operators
      Natural y = n;
      if (y == 5)
	cout << y << " == " << 5 << endl;
      else
	{
	  cout << y << " != " << 5 << endl;
	  
	  if (y < 5)
	    cout << y << " <  " << 5 << endl;
	  else
	    cout << y << " >  " << 5 << endl;
	}
    }

  Natural factn = factorial(n);


  if (debugFlag == "-debug")
    cout << "Factorial of " << n << " is " << factn << endl;
  
  Natural odds = factn / ((factorial(k) * factorial(n-k)));

  cout << "Odds of winning are 1 in " << odds << endl;

  return 0;
}



This post has been edited by CoryMore: 24 September 2013 - 05:04 PM

Was This Post Helpful? 0
  • +
  • -

#8 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 630
  • View blog
  • Posts: 2,107
  • Joined: 31-December 10

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 06:23 PM

Did you run the code through a debugger? If so, where did the segmentation fault occur?
Was This Post Helpful? 1
  • +
  • -

#9 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 104
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 07:19 PM

Program received signal SIGSEGV, Segmentation fault. 0x0000000000402cca in operator< (Natural const&, Natural const&) ()

I'm not great at debugging, I know it's pointing me to that function, but I'm not yet sure why.
Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3168
  • View blog
  • Posts: 9,578
  • Joined: 05-May 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 07:24 PM

Look at the other frames of the callstack. It will give you the hints you need to figure out what is happening.
Was This Post Helpful? 1
  • +
  • -

#11 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 104
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 07:30 PM

0x0000000000402cca in operator< (i=..., j=...) at natrual2.cpp:68
0x0000000000402ccf in operator< (i=..., j=...) at natrual2.cpp:68
...
That second line just continues, looks like I have a loop.
Was This Post Helpful? 0
  • +
  • -

#12 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3168
  • View blog
  • Posts: 9,578
  • Joined: 05-May 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 07:39 PM

You are calling yourself recursively infinitely:
bool operator< (const Natural& i, const Natural& j)
{
  return i < j;
}



You need to rewrite the body of the function so that you don't recursively call yourself.
Was This Post Helpful? 1
  • +
  • -

#13 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 104
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 07:50 PM

I've tried an if statement returning a false if i is not less than. That gave me the same issue. I also can't convert a const to a bool. Should I move the bools under the friend Natural and clear or run the normalize function after return?
Was This Post Helpful? 0
  • +
  • -

#14 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3168
  • View blog
  • Posts: 9,578
  • Joined: 05-May 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 07:52 PM

Hint: If you subtract j from i, and get a negative number, the i is less than j.
Was This Post Helpful? 1
  • +
  • -

#15 CoryMore  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 104
  • Joined: 26-June 12

Re: Errors implementing class functions "no match for operator"

Posted 24 September 2013 - 08:14 PM

Well, that seemed to solve that problem, now a new one arises <g. This one though doesn't contain a stack, so I guess it's a one time deal.


Another segmentation fault in line 13 of natural2.cpp leadingDigit [j] = i.leadingDigit[j];
Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3