我试图实现一个简单的程序来测试整数加法期间是否发生溢出:
#include <climits>
#include <iostream>
#include <string>
using namespace std;
string overflow(long a,long b){
return ((a+b)>UINT_MAX)?"true":"false";
}
int main(){
long a, b;
cout << "enter a and b: ";
cin >> a >> b;
string m = overflow(a,b);
cout << m;
return 0;
}
UINT_MAX=65535
所以我输入了65535和20,但是为什么写错了?
答案 0 :(得分:5)
鉴于unsigned int a, b
,此表达式永远无法评估为true
:
(a+b) > UINT_MAX
之所以不能true
,是因为UINT_MAX
是最大值,所以无论结果(a+b)
是多少都不能大于UINT_MAX
,因为会是一个矛盾。
您尝试使用更大的数据类型long
来解决此问题,但实际上并不保证在C ++中大于int
。您可能希望尝试使用long long
(尽管标准C ++中不存在此类型)。
与Java不同,C ++实际上并没有指定每种数据类型的大小,因此声称UINT_MAX=65535
并非普遍存在。只有无符号整数以16位保存的处理器才有效。对于32位,UINT_MAX
为4294967295
。
答案 1 :(得分:3)
unsigned int a = UINT_MAX;
unsigned int b = 20;
unsigned int c = a+b;
cout << c << endl;
//output
19
关于溢出检测的SO已经有一些问题(例如Best way to detect integer overflow in C/C++)。可能你会发现它们很有用
答案 2 :(得分:2)
您使用的是哪种编译器?
在大多数系统中,整数是32位有符号类型,它提供+/- 21亿(给予或接受一对)。
65535是一个16位的值,所以在它上面加20不会有太大作用,但我很惊讶它会给出错误。
答案 3 :(得分:1)
很多问题:
65535是2 ^ 16或2个字节,其中long通常是4个字节长或2 ^ 32。您可以将程序更改为使用通常为2个字节长的短路
有些编译器现在提供长度为2 ^ 64(长度必须至少为2 ^ 32但可以更大)。类似的规则适用于短裤。
你正在使用有符号长整数,这意味着一位用于表示一个符号,所以即使你使用输入65535的短路实际上是一个值-1(所以改为使用无符号短路)
如果你将两个无符号短路加在一起并将答案放入一个短路中,则总数不能超过65535,因为短路不能表示这么大的值。
答案 4 :(得分:1)
两件事
检查long的大小 - 如果它与int相同,则(a + b)将始终小于或等于UINT_MAX
对于4位整数,UINT_MAX = 4294967295
这完全取决于平台
答案 5 :(得分:1)
尝试:
string overflow(unsigned int a,unsigned int b)
{
return ((a > (std::numeric_limits<unsigned int>::max() - b))?"true":"false";
}
请记住,没有任何保证长的大于int,所以任何假设long将存储更大数字的代码都是有缺陷的。所以我们不能做总和来看看它是否溢出,因为它溢出时已经太晚了。因此重新排列符号,使表达式的一部分位于右侧。
答案 6 :(得分:0)
试试这个:
return ((a+b)>(long)UINT_MAX)?"true":"false";
另外,确保UINT_MAX确实是65535而不是更大。