[英]c++ Integer overflow in spite of using unsigned int and modulo operations
int orders=1000000000;
int mod=pow(10,9)+7;
unsigned int total=4294967295;
total=(orders*(orders+1))%mod;
total/=2;
return total;
预期答案= 21
但是得到
运行时错误:有符号整数溢出:1000000000 * 1000000001 不能用“int”类型表示
我也试过
int orders=1000000000;
int mod=pow(10,9)+7;
long long total=0LL;
total=(long long)(orders*(orders+1))%mod;
total/=2;
return total;
同样的错误
//使用最新的C++ 17标准编译clang 11。
我可以知道为什么会这样吗? 我想也许 long long 被截断为 int 因此是 0LL,但这仍然没有解决问题。
在其他编译器上尝试时,获取输出
对于第一个代码:
-243309312
对于第二段代码:
1904174336
考虑大小为 4 字节的整数范围
-2,147,483,648 to 2,147,483,647
Unsigned int max 4,294,967,295
现在声明
total=(orders*(orders+1))%mod;
将尝试将 orders*(orders+1) 放入带符号且最大值为“2,147,483,647”的 int 类型,因为 orders 是 int 类型。
所以乘法结果
1000000001000000000
并且它不在 int 范围内。因此您在这里有溢出问题。
为了更好的可见性运行这个
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;
基本上问题是你在乘法之后有整数溢出。
要克服这个问题,您必须使用两种解决方案之一来处理主题。
unsigned long long int
使用第二种方法:
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.