Reputation: 6316
I was getting wrong answer by the below function.
vector<int> repeatedNumber(const vector<int> &A) {
int n = A.size();
long long linear_sum = 0,square_sum = 0;
int i = 0;
for(;i<n;i++){
linear_sum += A[i]; //LINE 1
square_sum += A[i]*A[i]; //LINE 2
}
linear_sum = linear_sum - (n*(n+1))/2;
square_sum = square_sum - (n*(n+1)*(2*n+1))/6;
square_sum /= linear_sum;
vector<int> ans;
ans.push_back((linear_sum+square_sum)/2);
ans.push_back((-linear_sum+square_sum)/2);
return ans;
}
But when I replaced LINE 1 and LINE 2 with :
linear_sum += (long long)A[i];
square_sum += (long long)A[i]*(long long)A[i];
I got the correct answer.Why just typecasting the int to long long solves the problem.
Upvotes: 4
Views: 134
Reputation: 114579
When you multiply two int
values the result is computed as an int
.
If the values when multiplied are too big for an int
you get "undefined behavior" (in most common hardware you just get a seemingly random result).
For example 33554432
(i.e. 1<<25
== 225) is ok for a 32-bit integer, but its square 1125899906842624
(i.e. 250) is not.
Casting to long long
the terms before computing the multiplication you're hopefully expanding the range in which the computations are done correctly.
These problems are not present in languages that natively provide arbitrary precision integers like Python or Lisp.
Note it's possible that int
and long long
are indeed the same size (you can only be sure that a long long
is not smaller than an int
).
Upvotes: 3
Reputation: 3571
The key is here:
A[i]*A[i]
This can be too big, overflow the int
, and only after that, is converted to long long
, but.
(long long)A[i]*(long long)A[i];
is first converted and then multiply and may not overflow the long long
Upvotes: 2