Reputation: 43
I wrote a code like below.
#include <iostream>
#include <string>
#include <stack>
#include <cctype>
#include <algorithm>
#include <vector>
using namespace std;
long long int N, K;
int main() {
cin >> N >> K;
long long int result = 0;
int IntResult = 0;
for (long long int i = K; i <= N + 1; i++) {
result += 1 + (N + 1 - i) * i;
IntResult += 1 + (N + 1 - i) * i;
}
cout << result % (1000000000 + 7) << endl;
cout << IntResult % (1000000000 + 7) << endl;
return 0;
}
And when I input "141421 35623", this code outputs below.
141421 35623
220280457
619089693
The correct answer is "220280457". The result of int is wrong.
I put cout in a for loop and checked IntResult's value.
Then I found that IntResult became negative value in a for loop. It's overflowed!
But why? The max value of int is "2147483648". It's greater than "220280457".
And the process in for loop is just an addition, so I can't understand why it is overflowed.
Please help me!
Upvotes: 1
Views: 333
Reputation: 51825
In your loop, the expression 1 + (N + 1 - i) * i
(which is evaluated as a long long int
) quickly and frequently becomes greater than INT_MAX
, and this causes integer overflow when you try to add it to the (int
) result
.
Adding a quick 'check' to your code, as shown below, will demonstrate this:
int main()
{
cin >> N >> K;
long long int result = 0;
int IntResult = 0;
int count = 0;
for (long long int i = K; i <= N + 1; i++) {
// Check for intermediate overflow potential...
long long int lli = 1LL + (N + 1LL - i) * i;
if (lli > INT_MAX) cout << lli << " (" << ++count << ")" << endl;
result += 1 + (N + 1 - i) * i;
IntResult += 1 + (N + 1 - i) * i;
}
cout << result % (1000000000 + 7) << endl;
cout << IntResult % (1000000000 + 7) << endl;
return 0;
}
When I run this code on my platform (32-bit int
and 64-bit long long int
) with your given inputs (141421
and 35623
), the "overflow check" line actually happens 88,498 times! Here are the last three lines of output:
...
2147524241 (88498)
220280457
619089693
Furthermore, even though the above-checked addend may not, in itself, overflow an int
, the result of adding it to the existing (potentially non-zero) value in result
could still do so. Indeed, changing the 'check' line to this:
if ((lli + result) > INT_MAX) cout << lli << " (" << ++count << ")" << endl;
shows that the loop overflows on every iteration!
Upvotes: 1
Reputation: 14876
You overflow on first iteration.
1 + (N + 1 - i) * i
Is smaller than
(N - i)*i
First iteration:
(141421-35623)*35623
Whoops already overflow, which is UB in signed integers.
IntResult % (1000000000 + 7)
Happens afterwards, and has no meaning as IntResult contains a unknown value.
Upvotes: 1