使用long int避免溢出是一个好习惯吗?

时间:2015-06-20 18:51:12

标签: c++

假设我已声明以下变量:

some_dataType a,b,c;  //a,b,c are positive
int res;
res=a+b-c;

我已收到变量res无法跨越整数限制的信息。为了避免a+ba+b-c的表达式溢出,我有以下选项 -

  1. 将a,b,c声明为long int
  2. (a-c) + B
  3. (long int)(a + b-c)//或其他类型的广告
  4. 我的问题是以上哪项是好的做法。另外,为了摆脱这一切,我更喜欢做选项1.但是它可能会增加程序的内存大小(不过对于这个程序,但对于大型应用程序而言)。 假设:long int大于int谢谢@Retired Ninja

2 个答案:

答案 0 :(得分:4)

没有简单,通用,可移植的方法来避免整数溢出。

使用更宽的整数类型不是一般解决方案,因为无法保证存在更宽的整数类型。类型intlong在某些系统上的大小相同是很常见的。 32位系统通常使intlong 32位;甚至一些64位系统也做同样的事情。一些64位系统同时使intlong为64位。

您写道:

  

我收到的信息是变量res不能超过整数限制。

最好小心术语。虽然类型名称int显然是单词“integer”的缩写,但这些单词不是同义词。在C和C ++中,int只是几个整数类型中的一种;其他人包括unsigned charlong long

大概你的意思是res的值不得超出int类型的范围,INT_MININT_MAX

如果您使用long long作为结果,则可能会避免溢出;然后,您可以将结果与值INT_MININT_MAX进行比较,如果超出范围,则采取适当的纠正措施。但intlong long仍然可能是64位。你用它做什么取决于你的代码需要多么可移植。

在事后,您无法安全地检查有符号整数加法或减法是否溢出。带符号算术的溢出会导致未定义的行为。通常结果会结束,但原则上您的程序可能会在您有机会检查结果之前崩溃。

某些编译器可能会提供执行安全签名算术的函数,并告诉您是否存在溢出。请参阅编译器的文档。

在执行操作之前,有多种方法可以测试操作数。它们很复杂,而且我懒得弄清楚细节,但简单地说:

  • 如果+的操作数符号相反,或者一个操作数为0,则添加是安全的。
  • 如果两个操作数均为正数,则x不超过INT_MAX - y时添加是安全的。
  • 如果两个操作数均为负数,则y不小于INT_MIN - y时添加是安全的。

我不保证以上内容是完全正确的*我只是把它写在了我的头顶上),但在大多数情况下,它可能比它的价值更多的努力。

答案 1 :(得分:0)

信任,但请确认:

assert(a > 0);
assert(b > 0);
assert(c > 0);
assert((long)a - (long)c + (long)b <= INT_MAX);

int res = a - c + b;