Reputation: 792
int orders=1000000000;
int mod=pow(10,9)+7;
unsigned int total=4294967295;
total=(orders*(orders+1))%mod;
total/=2;
return total;
expected Answer= 21
BUT getting
runtime error: signed integer overflow: 1000000000 * 1000000001 cannot be represented in type 'int'
I also tried
int orders=1000000000;
int mod=pow(10,9)+7;
long long total=0LL;
total=(long long)(orders*(orders+1))%mod;
total/=2;
return total;
Same error
//Compiled with clang 11 using the latest C++ 17 standard.
May I know why this is happening? I thought maybe long long is getting truncated to int hence the 0LL, But still that didn't solve the issue.
When tried on other compiler, getting output
for 1st code:
-243309312
for second peice of code:
1904174336
Upvotes: 0
Views: 701
Reputation: 37512
Basically problem is you have integer overflow just after multiplication.
To overcome this problem you have to approach topic using one of two solutions.
unsigned long long int
Using second approach:
constexpr unsigned mutiplyModulo(unsigned a, unsigned b, unsigned n)
{
unsigned m = 1, w = 1;
while (m) {
if (b & m)
w = (w + a) % n;
a = (a << 1) % n;
m <<= 1;
}
return w;
}
constexpr unsigned int intpow(unsigned int x, unsigned int n)
{
unsigned int r = 1;
while (n) {
if (n & 1)
r *= x;
x *= x;
n /= 2;
}
return r;
}
unsigned int foo(unsigned int orders)
{
constexpr auto mod = intpow(10u, 9u) + 7u;
unsigned int total = mutiplyModulo(orders, orders + 1, mod);
total /= 2;
return total;
}
https://godbolt.org/z/ePW7WxcTe
Upvotes: 1
Reputation: 610
integer range considering size to be 4 bytes
-2,147,483,648 to 2,147,483,647
Unsigned int max 4,294,967,295
Now the statement
total=(orders*(orders+1))%mod;
will try to put orders*(orders+1) into type int which is signed and has max value of "2,147,483,647" as orders is type of int.
so the multiplication results
1000000001000000000
and it's not in range of int .hence you have overflow issue here .
For better visibility run this
int orders=1000000000;
int mod=pow(10,9)+7;
unsigned int total=4294967295;
total=(orders*(orders+1))%mod;
total/=2;
cout<< "result= "<<total<<"\n";
int val = (orders*(orders+1));
std::cout<<"val = "<<val;
unsigned int t=(-486618624)%mod;
std::cout<<"\nresult 2 = "<<t/2;
Upvotes: 1