Overloading Operator + in C++ - c++

Ok, I am working through a book and trying to learn C++ operator overloading. I created a BigInt class that takes a single int (initially set to 0) for the constructor. I overloaded the += method and it works just fine in the following code:
BigInt x = BigInt(2);
x += x;
x.print( cout );
The code will output 4. So, then I was working on overloading the global operator + using the following code:
BigInt operator+(const BigInt lhs, const BigInt rhs)
{
BigInt returnValue(lhs);
returnValue += rhs;
return returnValue;
}
This also works fine for the following code:
BigInt x = BigInt(1);
BigInt y = BigInt(5);
BigInt z = x + y;
z.print();
This prints out 6. However, when I try to execute the following code, it just doesn't work. The book doesn't explain very well and implies that it should simply work.
BigInt x = BigInt(1);
BigInt z = x + 5;
z.print();
This prints out 1. I'm not sure why z is 1 when it should be 6. I googled online and on stackoverflow but I couldn't find anyone else that was having a problem exactly like this. some were close, but the answers just didn't fit. Any help is much appreciated!

most likely problem is in += operator. Post code for it.

You need an overload for adding an int to BigInt; the constant 5 in your example is of type int, not BigInt. Something like this should work:
BigInt operator+(const BigInt lhs, const int rhs)
{
BigInt returnValue(rhs);
returnValue += lhs;
return returnValue;
}
You might want one for operator+(const int lhs, const BigInt rhs) too.

The following super-simplified code (the minimum I can add to include all your code and make it into a valid stand-alone executable program):
#include <iostream>
class BigInt
{
public:
BigInt(int i): _i(i) {}
void print() { std::cout << "BigInt(" << _i << ")\n"; }
void operator +=(const BigInt rhs) { _i += rhs._i; }
private:
int _i;
};
BigInt operator+(const BigInt lhs, const BigInt rhs)
{
BigInt returnValue(lhs);
returnValue += rhs;
return returnValue;
}
int main() {
BigInt x = BigInt(1);
BigInt y = BigInt(5);
BigInt z = x + y;
z.print();
BigInt ax = BigInt(1);
BigInt az = ax + 5;
az.print();
return 0;
}
emits, as predictable:
BigInt(6)
BigInt(6)
Please make the minimum possible alterations to this working code to reproduce the bug you observe -- that will of course show where your bug exactly lies.

The code you've posted looks fine and should work. Problems you're seeing are almost certainly due to the copy constructor or assignment operator of your BigInt class.

Related

Overloading = in bignum implementation

I am writing a bignum implementation and in it I overloaded operators + and =. Here is my code that does it:
BigNum& operator+(const BigNum& b ) {
BigNum sum;
int carry=0;
for (int i=0; i<N;i++){
sum.dig[i]=(dig[i]+b.dig[i]+carry)%10;
carry=(dig[i]+b.dig[i]+carry)/10;
}
return sum;
}
BigNum& operator=(const BigNum& rhs ) {
for (int i=0; i<N; i++){
dig[i]=rhs.dig[i];
}
return *this;
}
They both seem to be working well on their own (I can assign a bignum to a bignum correctly and add two bignums correctly) but when I try to combine them I get answers that seem to be random. So if a and b are bignums, it's okay if I say
BigNum c=b;
and
cout<<a+b;
but
a=a+b;
gives an unexpected result.
You are returning a reference to a local variable sum from your + operator. You can't meaningfully return references or pointers to local variables. Because of this error the behavior of your code is undefined, which the reason for your "unexpected results".
Since you are implementing a regular binary +, you have to return the result by value
BigNum operator +(const BigNum& b) const {
BigNum sum;
...
return sum;
}
As an additional note, binary + make more sense as a standalone (possibly friend) function, not as a class member. If you want to keep it as a class member, at least declare it const (see above).
A separate question is what dig is, what N is and whether your class violates the Rule Of Three. But it is impossible to say from what you posted.
This may not answer your question but I believe it will improve your code and as such, it's a "suggestion".
It would be wise to implement the + operator to create a temporary that invokes the += operator.
For example:
BigNum& operator += (const BigNum &other) {
int carry = 0;
for (int i = 0; i < digits_length; ++i) {
int temp = digit[i];
digit[i] = (digit[i] + other.digit[i] + carry) % 10;
carry = (temp + other.digit[i] + carry) / 10;
}
return *this;
}
BigNum operator + (const BigNum& other) const {
return BigNum(*this) += other;
}

Overloading the += operator

I have the following code to overload the + and += operators respectively for the class Date. The operator + was successfully overloaded, and it will take an integer n and increase Date objects by n days. This is done by applying the next_day function n times.
inline Date operator+(Date d, int n)
{
for(char j=1; j<=n; j++){
d=d.next_day(d);
}
return d;
}
inline Date operator+=(Date d, int n)
{
Date p=d+n;
return p;
}
Having overloaded the + operator, I'm using it to define the overloading of += as well. But although no errors occurred in compilation, when I use the overloaded += it doesn't seem to have any effect.
Here's my main.cpp:
#include <iostream>
#include "Date.h"
using namespace std;
int main() {
Date Initialday = Date (12,1,2012);
Initialday+=1;
cout <<"Next day = "<< Initialday <<endl;
return 0;
}
Running the main function still gives me 12/1/2012 instead of 12/2/2012. What am I doing wrong? Note: I've already overloaded << to output Date objects in a readable format, so I don't think that's the issue.
The simple fix is to take your Date object in by reference, modify it, and return it by reference. That's the expected behavior of operator+=.
inline Date& operator+=(Date &d, int n)
{
d = d + n;
return d;
}
However, to implement operator+= in terms of operator+ is backwards. It should be the other way around. operator+= should act on the members of the object, changing them directly. Then operator+ should be implemented in terms of that:
inline Date& operator+=(Date& lhs, int rhs)
{
... // code here to modify lhs directly
return lhs;
}
inline Date operator+(Date lhs, int rhs)
{
return lhs += rhs;
}
The main problem is that your += is creating a new Date object and returning it. That is the wrong semantics, plus you do not assign that return value to anything. A += operator should act on the instance it is applies to and return it by reference:
inline Date& operator+=(Date& d, int n) {
return d = d + n;
}
Usually, this would be implemented as a member function, with + implemented in terms of +=:
class Date
{
public:
Date& operator+=(int n) {
// perform whatever operation is required using
// the state of the instance.
return *this;
}
};
inline Date operator+(Date lhs, int rhs) {
return lhs += rhs; // calls member +=
}
The cleanest way would be to provide a time duration class, and implement all the operators in terms of a Date and a TimeDuration:
struct TimeDuration { .... };
class Date
{
public:
Date& operator+= (const TimeDuration& rhs) { .... }
};
inline Date operator+(Date lhs, const TimeDuration& rhs) { return lhs += rhs; }

c++ Operator overloading,

Whats wrong with my code shown below? please somebody throw some light. Thanks for your time !
#include<iostream.h>
using namespace std;
struct mydata{
int mx;
mydata(int x = 0){}
mydata operator+(const mydata& rhs){
mydata temp(rhs);
return temp;
}
operator int() const{ return mx; }
operator double() const{ return mx; }
};
int main(){
mydata d;
mydata r = d + 5; // L1
5 + d; // L2
d + d; // L3
}
First, you haven't stated what the problem is, but presumably you want an operator+ that sums the mx values of two mydata objects:
mydata operator+(const mydata& rhs){
return mydata (mx + rhs.mx);
}
Next, I would suggest making this a non-member function, so that the LHS and RHS get treated in the same way, fixing the problem in L2:
mydata operator+(const mydata& lhs, const mydata& rhs){
return mydata (lhs.mx + rhs.mx);
}
Finally, you will have an ambiguous overload remaining, because the compiler cannot decide whether to use the built-in operator+(int,int) or your own operator+(const mydata&, const mydata&). You can fix this by removing the cast operators int() and double().
See demo here.
The problem (stated the comment) is that compiler doesn't know which + you want to execute:
(double)d + 5
or
(int)d + 5
In order to resolve this ambiguoity, you should point the type conversion, or replace one of these operators by a named function:
operator int() const{ return mx; }
operator double() const{ return mx; }
If you want instead use d + mydata(5) you should write so, because the above variants are more likely to be applied
You could provide a few non-member operator+ to enable operator+ with different data type:
mydata operator+(const mydata& lhs, const mydata& rhs){
return mydata (lhs.mx + rhs.mx);
}
mydata operator+(int mx, const mydata& rhs){
return mydata (rhs.mx+mx);
}
mydata operator+(const mydata& lhs, int mx){
return mydata(lhs.mx+mx);
}
You can't do 5 + d. 5 can not be converted to class object like this. For this you need to get the operator + definition out of the class method. (in my knowledge preferably friend).

error C2593: 'operator +' is ambiguous

If I have the following files, I get this error (c2593 in VC9).
If I un-comment the prototype in main.cpp, the error disappears. I need to maintain the same functionality while keeping the class out of main.cpp. How can I do that?
Thanks.
main.cpp:
#include "number.h"
//const Number operator + (const Number & lhs, const Number & rhs);
int main(void)
{
Number n1(2); // n1 = 2
Number n2(9,3); // n2 = 3
Number n3 = n1+n2; // n3 = 5
}
number.h:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
};
number.cpp:
#include "Number.h"
const Number operator + (const Number & lhs, const Number & rhs)
{
Number tmp;
tmp.num = lhs.num + rhs.num;
return tmp;
}
Try putting the prototype in the Number header file:
number.h:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
};
const Number operator + (const Number & lhs, const Number & rhs);
number.cpp:
#include "Number.h"
const Number operator + (const Number & lhs, const Number & rhs)
{
Number tmp;
tmp.num = lhs.num + rhs.num;
return tmp;
}
main.cpp:
#include "number.h"
int main(void)
{
Number n1(2); // n1 = 2
Number n2(9,3); // n2 = 3
Number n3 = n1+n2; // n3 = 5
}
You never declare operator + in number.h, you only define it in number.cpp - therefore, when you include number.h in main.cpp, it doesn't know where to go to find operator +.
You must put the declaration of operator + in number.h, outside of the class, then define it in number.cpp
That commented line should go in number.h
EDIT: in number.h but as a free function.
One other thing to note with your code before you go back to us with a very similar question: Better remove the operator int and operator double functions. They will cause you major headache. Let's make a few examples:
Number a, b;
1 + b;
// ambiguous: operator+(int, int) or
// operator+(Number, Number) ?
// did you intend to use those for this case?
float x = a;
// ambiguous: from int -> float or
// double -> float ?
In the original situation you had, your addition was ambiguous, because there were operator+(double, double) and operator+(int, int) builtin operators considered and they were equally well. Others solved that problem. But before you start and run into these other problems, better remove the conversion functions and insert explicit functions like asDouble or something similar.
Apart from other's answers to declare operator+ in the header file, I suggest you to have operator+= in your struct as well.
struct Number
{
// your other declarations.
Number& operator+=(const Number& other)
{
this->num += other.num;
return *this;
}
};
const Number operator+(const Number& lhs, const Number& rhs)
{
Number ret(lhs);
ret += rhs;
return ret;
}
This way it is efficient to call x += y; instead of x = x + y;
Personally I like it better to declare the operators inside the class:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
Number operator+(const Number &arg) const;
};
and then:
Number Number::operator+(const Number &arg)
{
...
}

Handling large numbers in C++?

What is the best way to handle large numeric inputs in C++ (for example 10^100)?
For algorithms I usually switch over to ruby and I sometimes use strings.
Any other good methods?
It sounds like you're looking for a way to enter Arbitrary Precision numbers.
here are two libraries you could use: GMP and MAPM
Check out The Large Integer Case Study in C++.pdf by Owen Astrachan. I found this file extremely useful with detail introduction and code implementation. It doesn't use any 3rd-party library. I have used this to handle huge numbers (as long as you have enough memory to store vector<char>) with no problems.
Idea:
It implements an arbitrary precision integer class by storing big int in a vector<char>.
vector<char> myDigits; // stores all digits of number
Then all operations related to the big int, including <<, >>, +, -, *, ==, <, !=, >, etc., can be done based on operations on this char array.
Taste of the code:
Here is the header file, you can find its cpp with codes in the pdf file.
#include <iostream>
#include <string> // for strings
#include <vector> // for sequence of digits
using namespace std;
class BigInt
{
public:
BigInt(); // default constructor, value = 0
BigInt(int); // assign an integer value
BigInt(const string &); // assign a string
// may need these in alternative implementation
// BigInt(const BigInt &); // copy constructor
// ~BigInt(); // destructor
// const BigInt & operator = (const BigInt &);
// assignment operator
// operators: arithmetic, relational
const BigInt & operator += (const BigInt &);
const BigInt & operator -= (const BigInt &);
const BigInt & operator *= (const BigInt &);
const BigInt & operator *= (int num);
string ToString() const; // convert to string
int ToInt() const; // convert to int
double ToDouble() const; // convert to double
// facilitate operators ==, <, << without friends
bool Equal(const BigInt & rhs) const;
bool LessThan(const BigInt & rhs) const;
void Print(ostream & os) const;
private:
// other helper functions
bool IsNegative() const; // return true iff number is negative
bool IsPositive() const; // return true iff number is positive
int NumDigits() const; // return # digits in number
int GetDigit(int k) const;
void AddSigDigit(int value);
void ChangeDigit(int k, int value);
void Normalize();
// private state/instance variables
enum Sign{positive,negative};
Sign mySign; // is number positive or negative
vector<char> myDigits; // stores all digits of number
int myNumDigits; // stores # of digits of number
};
// free functions
ostream & operator <<(ostream &, const BigInt &);
istream & operator >>(istream &, BigInt &);
BigInt operator +(const BigInt & lhs, const BigInt & rhs);
BigInt operator -(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, int num);
BigInt operator *(int num, const BigInt & rhs);
bool operator == (const BigInt & lhs, const BigInt & rhs);
bool operator < (const BigInt & lhs, const BigInt & rhs);
bool operator != (const BigInt & lhs, const BigInt & rhs);
bool operator > (const BigInt & lhs, const BigInt & rhs);
bool operator >= (const BigInt & lhs, const BigInt & rhs);
bool operator <= (const BigInt & lhs, const BigInt & rhs);
If you wish to make your own code for the purpose try using strings to store big numbers... you can then create basic ops like + - / * on them... for example -
#include <iostream>
using namespace std;
string add (string &s1, string &s2){
int carry=0,sum,i;
string min=s1,
max=s2,
result = "";
if (s1.length()>s2.length()){
max = s1;
min = s2;
} else {
max = s2;
min = s1;
}
for (i = min.length()-1; i>=0; i--){
sum = min[i] + max[i + max.length() - min.length()] + carry - 2*'0';
carry = sum/10;
sum %=10;
result = (char)(sum + '0') + result;
}
i = max.length() - min.length()-1;
while (i>=0){
sum = max[i] + carry - '0';
carry = sum/10;
sum%=10;
result = (char)(sum + '0') + result;
i--;
}
if (carry!=0){
result = (char)(carry + '0') + result;
}
return result;
}
int main (){
string a,b;
cin >> a >> b;
cout << add (a,b)<<endl;
return 0;
}
Are you looking for how to perform operations on the large inputs you receive? There is a big integer C++ library (similar to Java) that allows you to perform arithmetic operations...
assuming you are talking about inputting numbers, double precision would get you up to 1.7976931348623157 x 10^308
You might want to have a look to gmplib, an arbitrary precision number handling library for C and C++
If you want it to be accurate, you need a library made to deal with big numbers. Java has BigInt that will always be accurate no matter how many digits you want to take it to, and provides math operations on them. All the source code is included, you could transfer it, but this really isn't the kind of thing C++ is best at--I'd use a JVM based language and use one of the Big libraries.
I don't think I'd use ruby for this unless you wanted it to be slow, and I'm assuming that since you are talking about C++, speed is somewhat of a design consideration.
As others have already pointed out, there are various bignum/arbitrary precision libraries in C++ that you would likely find useful. If speed isn't necessary, I'm under the impression that Python and Lisp both use bignums by default.
Consider boost::cpp_int
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
int main()
{
using namespace boost::multiprecision;
cpp_int u = 1;
for(unsigned i = 1; i <= 100; ++i)
u *= i;
// prints 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 (i.e. 100!)
std::cout << u << std::endl;
return 0;
}
Well I think the best way to do such arithmetic calculation is by using strings. Give input as command line arguments and then manipulate the whole logic using string functions like atoi() and itoa()! But, hey can this be done for multiplication and Division? I think in this way strlen of strings entered doesn't matter for programming for compiler until the logic is fine.