Problems with const

Hello I have written some code and I wanted to avoid that the parameters are getting copied every time the function gets called because that operation is quite time expensive. So I used BigInt operator + (const BigInt & a,const BigInt & b) {
(BigInt is a class with two objects like this) :
1
2
bool negative;
vector <int> digits;


Now I have written my code like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
BigInt operator + (const BigInt & a,const BigInt & b) {
	if (b.negative==a.negative) {
		BigInt res;
		//...... irrelevant
		
		return res;
	} else {
		if (a.negative) {
			//a.negative=false;
			return b-a;
		} else {
			//b.negative=false;
			return a-b;
		}
	}
}


Now I have a problem because I need to perform the subtraction but before that I should have the negative changed but I can't do this anymore because it is const. No matter what I don't want to make a new BigInt and copy all the elements to it because if I do that then my code is about 50% slower...

If anything is not clear feel free to ask me.
Thanks in advance
Jannes
Last edited on
If you have operator-() defined, you could try doing something like
1
2
3
4
5
if (a.negative) {
    return b - (-a);
} else {
    return a - (-b);
}
But BigInt operator-() const; would return a copy of 'a'.

You may have private subtract/add operations that do not take into account the sign of the operands, then you have operator-(a,b) as a wrapper that will correctly determine the sign of the result and call the appropriate function.
They should take into account the sign of the operands because it is quite easy to see that 5+3 and 5+(-3) require a different function to work.

EDIT: I think I know what you mean. I'll make a sub function and an add function that don't look to the signs. and then depending on the sign I will call the correct function without altering the signs.

EDIT2:
This became my final code and it works now :) (without copying anything) thanks to you ne555.

I would be very grateful if anyone could check my code for any possible errors. Maybe I added two values when they should be subtracted or anything like that. Thanks in advance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
void add (BigInt & res,const BigInt &a,const BigInt &b) {
	//value of res is altered.
}

void sub(BigInt & res,const BigInt & a,const BigInt & b) {
	//value of res is altered.
}

BigInt operator + (const BigInt & a,const BigInt & b) {
	BigInt res;
	res.digits.reserve(a.digits.size()+2);

	if (b.negative==a.negative) {
		if (b.digits.size()>a.digits.size()) {
			add(res,b,a);
		} else {
			add(res,a,b);
		}
	} else if (a.negative) {
		if (b>a) {
			sub(res,b,a);
			res.negative=false;
		} else {
			sub(res,a,b);
			res.negative=true;
		}
	} else {
		if (a>b) {
			sub(res,a,b);
			res.negative=false;
		} else {
			sub(res,b,a);
			res.negative=true;
		}
	}
	return res;
}

BigInt operator - (const BigInt & a,const BigInt & b) {
	BigInt res;
	res.digits.reserve(a.digits.size()+2);

	if (!b.negative && !a.negative) {
		if (a>b) {
			sub(res,a,b);
		} else {
			sub(res,b,a);
			res.negative=true;
		}
	} else if (b.negative && a.negative) {
		if (b>a) {
			sub(res,b,a);
		} else {
			sub(res,a,b);
			res.negative=true;
		}
	} else if (b.negative) {
		add(res,a,b);
	} else {
		add(res,a,b);
		res.negative=true;
	}

	return res;
}
Last edited on
1
2
//res.digits.reserve(a.digits.size()+2);
res.digits.reserve( std::max(a.digits.size(), b.digits.size()) + 1 );


1
2
else if (a.negative) {
		if (b>a) //I suppose that you do take into account the sign in operator<, so this is a tautology 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
BigInt operator + (const BigInt & a,const BigInt & b) {
	BigInt res;
	res.digits.reserve(a.digits.size()+2);

	if (b.negative==a.negative) { //-|a| + -|b| = -( |a|+|b| )
		if (b.digits.size()>a.digits.size()) {
			add(res,b,a);
		} else {
			add(res,a,b);
		}
	} else if (a.negative) { //-|a| + |b| = |b| - |a|
		if (b>a) {
			sub(res,b,a);
			res.negative=false;
		} else {
			sub(res,a,b);
			res.negative=true;
		}
	} else { // |a| + -|b| = |a|-|b|    or    |a|+|b| = |a|+|b|
		if (a>b) {
			sub(res,a,b);
			res.negative=false;
		} else {
			sub(res,b,a);
			res.negative=true;
		}
	}
	return res;
}
you missed the case were 'a' and 'b' are positive.
That could be done as
1
2
3
4
if( a.sign == b.sign ){
   add(res, a, b);
   res.sign = a.sign;
}
Last edited on
Thanks for pointing out the mistakes with the reserve and the tautology :)
The case where a and b are positive is already handled because in my code I had if (b.negative==a.negative) { and if a.negative and b.negative are both false (which means they are both positive) then the equality will return true.
that's right, I must have misread it.
However, ┬┐where do you set the sign of the result?
Topic archived. No new replies allowed.