测试整数加法中的溢出

时间:2010-08-06 09:59:44

标签: c++

  

可能重复:
  Best way to detect integer overflow in C/C++

我试图实现一个简单的程序来测试整数加法期间是否发生溢出:

#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,但是为什么写错了?

7 个答案:

答案 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_MAX4294967295

相关问题

另见

答案 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)

两件事

  1. 检查long的大小 - 如果它与int相同,则(a + b)将始终小于或等于UINT_MAX

  2. 对于4位整数,UINT_MAX = 4294967295

  3. 这完全取决于平台

答案 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而不是更大。