Thread: Overloading operator++

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    53

    Overloading operator++

    Hi,

    I'm having some trouble trying to overload the operator ++. When I try to overload it, it does not output the correct output that I want. I want to try to make the first input to be incremented, but I cannot find a way how. Can someone please help me out?

    Here's an output that I am trying to achieve. "A" is the first output that I am trying to increment, which is 34.
    For example:
    the input: 34 45

    the output:
    cout << A++ << A
    34 35

    cout << ++A << A
    36 36


    Here's my code:
    HugeInteger.h
    Code:
    #include <iostream>
    using std::cin;
    using std::cout;
    using std::endl;
    using std::istream;
    using std::ostream;
    
    class HugeInteger
    {
    public:
    	HugeInteger( long long value = 0LL ); 
    	HugeInteger( const char *str );
    
    	HugeInteger & operator +=( const HugeInteger & RHS);
    	HugeInteger & operator -=( const HugeInteger & RHS); 
    
    	HugeInteger operator -(void)const;
    	HugeInteger operator ~(void)const; // will overload ~ as abs operator
    	bool operator ==( const HugeInteger & RHS)const;
    	bool operator <( const HugeInteger & RHS)const;
    	bool operator !(void)const;
    
    	void input( const char *str );
    
    	operator double(void)const;
    
    	HugeInteger & operator ++ (void);
    	HugeInteger operator ++ (int);
    
    private:
    	const static int MaxDigit = 40;  
    	bool negative;  
    	short hugeInt[ MaxDigit ]; 
    
    	friend istream & operator >> (istream & src, HugeInteger & value);
    	friend ostream & operator << (ostream & dest, const HugeInteger & value);
    };
    
    //overloads the unary + operator for the HugeInteger class
    //will return true if operand is != zero
    bool operator +( const HugeInteger);

    HugeInteger.cpp
    Code:
    #include "HugeInteger.h"
    
    // ctor converts a long long into a HugeInteger
    HugeInteger::HugeInteger( long long value )
    {
    	// set all MaxDigit digits to zero to start
    	this->negative = false;
    	if (value < 0LL){ // 0LL is constant literal 0 of type long long
    		this->negative = true;
    		value = - value; // make the value positive	                
    	}
    
    	for( int i = 0; i < MaxDigit; i++ )
    		this->hugeInt[i] = 0;
    
    	// convert individual digits of input value into a HugeInteger
    	for( int j = MaxDigit-1; j >= 0 && value != 0LL; j-- )
    	{
    		this->hugeInt[j] = value % 10;
    		value /= 10;
    	}
    
    	// test to make sure that HugeInteger was able to contain value
    
    	if (value != 0LL){
    		*this = 0LL; // set to -0, to signal overflow
    	    this->negative = true; //   Possibly should increase value assigned
    	}                          //   to MaxDigit to fix this problem.
    }
    
    // converts string into a HugeInteger object
    HugeInteger::HugeInteger( const char *str )
    {
    	this->input( str ); 
    }
    
    // Adds into the HugeInteger pointed to by the "this" pointer the HugeInteger op.
    // Then the calculated result is returned
    HugeInteger & HugeInteger::operator +=( const HugeInteger &op )
    {
    	// if the signs of the 2 numbers are opposites, we need to do subtraction
    	//     remember that x + y  ==  x - (-y)
    	if ((this->negative && !(op.negative)) || (!(this->negative) && op.negative))
    		return this->operator -=(-op);
    
    	// NOTE: From here on, we know the two operands are the same sign
    
    	int carry = 0;
    	for (int i = MaxDigit - 1; i >= 0; i-- )
    	{
    		this->hugeInt[i] = this->hugeInt[i] + op.hugeInt[i] + carry;
    		if (this->hugeInt[i] > 9 ){
    			this->hugeInt[i] -= 10;
    			carry = 1;
    		}
    		else 
    			carry = 0;
    	}
    
    	// test for overflow
    	if (carry == 1){
    		*this = 0LL; // just set to -0 (LL is for type long long)
    		this->negative = true;  // to signal that an overflow occurred
    	}
    
    	return *this;
    }
    
    
    // Subracts from the HugeInteger pointed to by the "this" pointer the HugeInteger op
    // Then the calculated value is returned.
    HugeInteger & HugeInteger::operator -=( const HugeInteger &op )
    {
    	// if the signs of the 2 numbers are opposites, we need to do addition
    	//     remember that x - y  ==  x + (-y)
    	if ((this->negative && !(op.negative)) || (!(this->negative) && op.negative)){
    		return this->operator +=(-op);
    	}
    
    	// NOTE: From here on, we know the two operands are the same sign
    
    	HugeInteger bigger, smaller; // used to make code easier to understand
    
    	if ((*this) == op){ 
    		*this = 0LL;             
    		this->negative = false;
    		return *this;
    
    	} else if ( (~op) < (~(*this))){ // is magnitude of LHS > RHS
    
    		bigger = *this;
    		smaller = op;
    
    	} else { // magnitude of RHS > LHS
    
    		smaller = *this;
    		bigger = op;
    		*this = -(*this); // result needs to be negated
    	}
    
    	// subtract smaller (in magnitude) from biggger (in magnitude)
    	int borrow = 0;
    	short top, bottom, result;
    	for ( int i = MaxDigit-1; i >= 0; i-- )
    	{
    		top = bigger.hugeInt[i];
    		bottom = smaller.hugeInt[i];
    
    		if (borrow == 1)
    		{
    			top -= 1;
    			borrow = 0;
    		}
    
    		result  = top-bottom;
    		if ( result < 0) //if true, we need to borrow
    		{
    			this->hugeInt[i] = (10+top)-bottom; // or result + 10;
    			borrow = 1;
    		}
    		else
    			this->hugeInt[i] = result;
    	}
    
    	return *this;
    }
    
    // Computes the negation of a HugeInteger
    HugeInteger HugeInteger::operator -(void)const
    {
    	HugeInteger temp = *this;
    	temp.negative = !temp.negative;
    
    	return temp;
    }
    
    // Computes and returns absolute value of operand
    HugeInteger HugeInteger::operator ~(void)const
    {
    	HugeInteger temp = *this;
    	temp.negative = false;
    	return temp;
    }
    
    bool HugeInteger::operator ==( const HugeInteger &op )const
    {
    	if(this->negative != op.negative)
    		return false;
    
    	for(int i = MaxDigit-1; i >= 0; i--)
    		if(this->hugeInt[i] != op.hugeInt[i])
    			return false;
    
    	return true;
    }
    
    bool HugeInteger::operator < ( const HugeInteger &op )const
    {
    	if(this->negative && (op.negative == false))
    		return true;
    
    	if(!(this->negative) && op.negative)
    		return false;
    
    	for(int i = MaxDigit-1; i >= 0; i--)
    	{
    		//if the numbers are both negative
    		if(this->hugeInt[i] < op.hugeInt[i])
    		{
    			if(!(this->negative))
    				return true;
    			
    			else	//if both numbers are negative
    				return false;
    		}
    		//if the numbers are both positive
    		else if(this->hugeInt[i] > op.hugeInt[i])
    		{
    			if(!(this->negative))
    				return false;
    			else	//if both numbers are negative
    				return true;
    		}
    	}
    	return false;
    }
    
    // Is_Zero operator
    bool HugeInteger::operator !()const
    {
    	for(int i = MaxDigit-1; i >= 0; i--)
    		if(this->hugeInt[i] == 0)
    			return true;
    
    	return false;
    }
    
    
    void HugeInteger::input( const char *str )
    {
    	// assume positive for now
    	this->negative = false;
    
    	// init. to all zeros first
    	for( int i = 0; i < MaxDigit; i++ )
    	{
    		this->hugeInt[i] = 0;
    	}
    
    	int len = (int)strlen( str );
    	int k = 0;
    
    	// if sign part of string, we need to process
    	// if + sign, we ignore since we start with assumption that 
    	// input string represents a positive number
    	if ((str[k] == '-') || (str[k] == '+')){ 
    		if (str[k] == '-'){ // if negative, set negative member to true
    			this->negative = true;
    		}
    
    		++k; // go to next char in string "str"
    		--len; // length of number is one less
    	}
    
    	if (len > MaxDigit) {  // if true, too many digits
    		this->negative = true; // return -0 to signal there
    		return;				   // was a problem
    	}
    		
    	for( int j = MaxDigit - len; j < MaxDigit; j++, k++ )
    	{
    		if (isdigit(str[k])){
    			this->hugeInt[j] = str[k] - '0';
    		}
    		else  // a problem with the string input 
    		{
    			*this = 0LL; // just set to -0 (LL is for type long long)
    			this->negative = true;  // to signal there was a problem
    			break;     
    		}
    	}
    }
    
    
    // Pre-increment operator
    HugeInteger & HugeInteger::operator ++ ()
    {
    	for(int i = MaxDigit-1; i >= 0; i--)
    	{
    		this->hugeInt[i] += this->hugeInt[i];
    	}
    	return *this;
    }
    
    // Post-increment operator
    HugeInteger HugeInteger::operator ++ (int)
    {
    	HugeInteger temp = *this;
    	for(int i = MaxDigit-1; i >= 0; i--)
    	{
    		temp.hugeInt[i] + temp.hugeInt[i];
    	}
    	return temp;
    }
    
    bool operator +( const HugeInteger value) // is not zero
    {
    	return !(!value);
    }
    
    // overloads the >> operator as a friend function
    istream & operator >> (istream & src, HugeInteger & value)
    {
    	char input_string[HugeInteger::MaxDigit+2];
    	src >> input_string;
    	value.input(input_string);
    	return src;
    }
    
    // overloads the << operator as a friend function
    ostream & operator << (ostream & dest, const HugeInteger & value)
    {
    	// find first non-zero digit
    	int i;
    	for( i = 0; (value.hugeInt[i] == 0) && (i < HugeInteger::MaxDigit); i++ )
    	{
    		;
    	}
    	
    	// if all zeros, just output a single 0
    	if (i == HugeInteger::MaxDigit)
    	{
    		dest << "0";
    		return dest;
    	}
    
    	// check if we need to ouput a negative sign
    	if (value.negative)
    		dest << '-';
    
    	// output remaining digits
    	for( ; i < HugeInteger::MaxDigit; i++)
    		dest << (short) value.hugeInt[i];
    
    	return dest;
    }
    Main.cpp
    Code:
    #include "HugeInteger.h" 
    #include <iso646.h>
    
    int main()
    {
    	HugeInteger A,B,C,D;
    
    	// input value for A & B
    	cout << "****** Test << & >> operators ******\n\n";
    	cout << "Input values for A and B: ";
    	cin >> A >> B;
    	cout << "\nA = " << A << "\nB = " << B;
    
    	// test increment operators
    	cout << "\n****** Test increment and decrement operators ******\n";
    	cout << "\nA = " << A << "\nB = " << B << "\n";
    	cout << "\ncout << A++ << A\n";
    	cout << A++ << "  " << A;
    
    	cout << "\n\ncout << ++A << A\n";
    	cout << ++A << "  " << A << "\n";
    
    	system("pause");
    
    	return 0;
    }

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I'm not sure I understand the question. By conventional design, post-increment copies its operand, does the operation, and returns the old value. Your program is working like any knowledgeable C++ programmer would expect.

  3. #3
    Registered User
    Join Date
    Jul 2007
    Posts
    53
    My problem is that the operator++ does not increment by one, instead it seems that it increments by the current input value.


    Code:
    // Pre-increment operator
    HugeInteger & HugeInteger::operator ++ ()
    {
    	for(int i = MaxDigit-1; i >= 0; i--)
    	{
    		this->hugeInt[i] += this->hugeInt[i];
    	}
    	return *this;
    }
    
    // Post-increment operator
    HugeInteger HugeInteger::operator ++ (int)
    {
    	HugeInteger temp = *this;
    	for(int i = MaxDigit-1; i >= 0; i--)
    	{
    		temp.hugeInt[i] + temp.hugeInt[i];
    	}
    	return temp;
    }

    Here's the example of my problem:
    With my current code:

    -the input: 34 45

    -the output:
    cout << A++ << A
    34 34

    cout << ++A << A
    68 68



    The correct output is suppose to be:
    cout << A++ << A
    34 35

    cout << ++A << A
    36 36



    My problem is that operator ++, does not increment by one, to achieve the correct output from the example above.

    I hope this makes sense about my problem

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Hmm, hugeInt is an array of digits correct?

    If that is the case than all that you should be doing for the post-increment is
    Code:
    HugeInteger temp(*this);
    
    int dig;
    //handle carries to next place
    for (dig = MaxDigits - 1; dig > 0 && hugeInt[dig] + 1 == 10; --dig) {
      hugeInt[dig] = 0;
    }
    ++hugeInt[dig]; //dig equals the correct place to increment
    return temp;
    Similar changes should be made for the pre-increment op.

    And because I'm not positive the << op is a sequence point, I would print the immediate result of the increment and the object itself separately.

    Code:
    cout << A++ << ' '; //during
    cout << A;          //after
    This avoids any undefined behavior that may mess with debugging printouts. You can be certain that if this looks wrong, it is the fault of the algorithm.

  5. #5
    Registered User
    Join Date
    Jul 2007
    Posts
    53
    Yes it is an array of digits. The digits are short values.

    Thanks for the help!!!

    But I have a question about the for loop:
    Code:
    for (dig = MaxDigits - 1; dig > 0 && hugeInt[dig] + 1 == 10; --dig)
    what does this portion of the code do:
    dig > 0 && hugeInt[dig] + 1 == 10;

    I tried to analyze it, but I'm a bit confused about the '&& hugeInt[dig] + 1 == 10'.
    If its possible can you explain this?

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Well when the digit is nine, you need to carry the addition to the next place, so you insert a zero and move to the left (or right, depending on the orientation of the places).

    Since I have a pretty good implementation of this handy I'll let you take a look at it.

    Code:
    void ctzn::HugeInt::operator++ ()
    {
        int dig;
    
        //carrying over ones
        for (dig = ctzn::HugeInt::maxdigits - 1; dig > 0 && digitsbuf[dig] + 1 == 10; --dig) {
            digitsbuf[dig] = 0;
        }
        ++digitsbuf[dig];
    
        //might rollover to the positive side
        negative = digitsbuf[dig] < 0;
    
        //might need to adjust front marker
        if (front == dig)
            --front;
    }
    
    
    ctzn::HugeInt ctzn::HugeInt::operator++ (int)
    {
        HugeInt result(*this);
        ++*this;
        return result;
    }
    Last edited by whiteflags; 08-18-2008 at 01:36 AM.

  7. #7
    Registered User
    Join Date
    Jul 2007
    Posts
    53
    Oh, I never thought of that for the number 9 when it is incremented. But what does this part do though?
    Code:
    //might need to adjust front marker
        if (front == dig)
            --front;
    Does it modify the first digit after the number 9?


    I have another question, what if the value inputted is a negative value, is there a way to increment it to a higher value? Such as when if it is -8, it would be incremented to -7.

    I have been trying to figure this out for a while, but I cannot seem to make it work for both the pre and post increment operators. It seems that my if statements have no effect on the values when incrementing. I've also tried to use the decrement operators, but it has no effect on the negative values.

    Here's my code:
    Code:
    // Pre-increment operator
    HugeInteger & HugeInteger::operator ++ ()
    {
    	int i;
    	for(i = MaxDigit-1; i > 0&& (hugeInt[i] + 1 == 10); --i)
    	{
    		this->hugeInt[i];
    	}
    	if(this->hugeInt[i] < 0 && this->negative == true) 
    	{
    		--(this->hugeInt[i]);
    	}
    
    	else
    	{
    		++this->hugeInt[i];
    	}
    
    	return *this;
    }
    
    // Post-increment operator
    HugeInteger HugeInteger::operator ++ (int)
    {
    	HugeInteger temp (*this);
    	int i;
    	
    	for(i = MaxDigit-1; i > 0 && (hugeInt[i] + 1 == 10); --i)
    	{
    		hugeInt[i] = 0;
    	}
    	if(this->hugeInt[i] < 0 && this->negative == true) 
    	{
    		--(this->hugeInt[i]);
    	}
    
    	else
    	{
    		++this->hugeInt[i];
    	}
    	
    	return temp;
    }
    
    // Pre-increment operator
    HugeInteger & HugeInteger::operator -- ()
    {
    	int base;
    	for(base= MaxDigit-1; base > 0 && hugeInt[base] + 1 == 10; --base)
    	{
    		hugeInt[base];
    	}
    	--hugeInt[base];
    	return *this;
    }
    
    // Post-increment operator
    HugeInteger HugeInteger::operator --(int)
    {
    	HugeInteger temp (*this);
    	int i;
    
    	for(i = MaxDigit-1; i >= 0 && (hugeInt[i] + 1 == 10); --i)
    	{
    		hugeInt[i] = 0;
    	}
    	--hugeInt[i];
    	return temp;
    }

    With this current code
    -The input is:
    -34 -45
    -The output is:
    cout << A++ << A
    -34 -35

    cout << ++A << A
    -36 -36


    The correct output is supposed to be:
    cout << A++ << A
    -34 -33

    cout << ++A << A
    -32 -32

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Code:
    cout << A++ << A
    You must not do this! It's undefined behaviour. There is no saying what this will output.

    You must split this into two lines.
    Code:
    cout << A++;
    cout << A;
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User Kernel Sanders's Avatar
    Join Date
    Aug 2008
    Posts
    61
    Quote Originally Posted by CornedBee View Post
    Code:
    cout << A++ << A
    You must not do this! It's undefined behaviour. There is no saying what this will output.

    You must split this into two lines.
    Code:
    cout << A++;
    cout << A;
    I was under the impression that the two <<'s were separate functions, giving that statement well defined behavior, unlike, say

    Code:
    int a = whatever;
    printf("%d %d", a++, a);
    Is that not true? (I'm a bit of a c++ nub and am better with c)

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Removing the sugar, it looks like this:
    Code:
    cout.operator<<(A.operator++(0)).operator<<(A)
    So, that may actually be defined, but only because A is passed by reference to the second function. We had a very recent thread in which it was shown that different compilers print different things if A was a primitive type.
    Thus, I'd avoid it like the plague even if it is actually defined.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. unary operator overloading and classes
    By coletek in forum C++ Programming
    Replies: 9
    Last Post: 01-10-2009, 02:14 AM
  2. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  3. Operator Overloading (Bug, or error in code?)
    By QuietWhistler in forum C++ Programming
    Replies: 2
    Last Post: 01-25-2006, 08:38 AM
  4. C++ Operator Overloading help
    By Bartosz in forum C++ Programming
    Replies: 2
    Last Post: 08-17-2005, 12:55 PM
  5. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM