Addition and Multiplication

I happened to type this in some part of the code and noted this ambiguity:

#define I_LIMIT 100000
#define ELE_LIMIT 1000000000

int main() {
	// your code goes here
	long sum = 0;
	for(int i=1; i<=I_LIMIT; i++)
		sum += ELE_LIMIT;
	cout << sum << endl;
	
	sum = (I_LIMIT*ELE_LIMIT);
	cout << sum << endl;
	
	return 0;
}

The output of sum variable in the two cases comes different:

100000000000000
276447232

Why such?

Search the forums. This is one of the most commonly asked questions.

I_LIMIT*ELE_LIMIT

Both of them are ints, there product is stored in int, which then overflows and the overflowed result gets stored in long. Make it (1LL *I_LIMIT*ELE_LIMIT) and see.

sum += ELE_LIMIT

It goes like sum=sum+ELE_limit , which is long+int \implies long. Result stored in long type, doesnt overflow and correct answer stored in sum.

1 Like

@vijju123’s answer is correct. I just want to add one more thing.

Why should we consider that I_LIMIT or ELE_LIMIT will be stored in a 32-bit data type instead of 64-bit data type? Then I stumbled on this StackOverflow answer which explains how does compiler determines the type of Integer Literals in C++ (given there are no explicit suffix in the literal). Basically, it checks if the literal can be contained in any of the following types in the same order and stops as soon as one of the types is able to hold it.

int
long int
long long int

Generally, int is a 32-bit data type and it can contain both the literals. Thus, I_LIMIT and ELE_LIMIT is of type int.

And just for the sake of completeness, the behavior that you have observed is how Implicit Type Conversion works. If you perform an arithmetic operation on two different data types, then the smaller one will be promoted (type promotion) to match with that of the larger data type and then the operation will be performed (this is what happens when you do sum += ELE_LIMIT).

In the other case, both the data type involved in the operation is int and thus the answer will be stored in an int.

1 Like