假设我已声明以下变量:
some_dataType a,b,c; //a,b,c are positive
int res;
res=a+b-c;
我已收到变量res
无法跨越整数限制的信息。为了避免a+b
中a+b-c
的表达式溢出,我有以下选项 -
(a-c)
+ B (long int)
(a + b-c)//或其他类型的广告我的问题是以上哪项是好的做法。另外,为了摆脱这一切,我更喜欢做选项1.但是它可能会增加程序的内存大小(不过对于这个程序,但对于大型应用程序而言)。 假设:long int大于int谢谢@Retired Ninja
答案 0 :(得分:4)
没有简单,通用,可移植的方法来避免整数溢出。
使用更宽的整数类型不是一般解决方案,因为无法保证存在更宽的整数类型。类型int
和long
在某些系统上的大小相同是很常见的。 32位系统通常使int
和long
32位;甚至一些64位系统也做同样的事情。一些64位系统同时使int
和long
为64位。
您写道:
我收到的信息是变量
res
不能超过整数限制。
最好小心术语。虽然类型名称int
显然是单词“integer”的缩写,但这些单词不是同义词。在C和C ++中,int
只是几个整数类型中的一种;其他人包括unsigned char
和long long
。
大概你的意思是res
的值不得超出int
类型的范围,INT_MIN
到INT_MAX
。
如果您使用long long
作为结果,则可能会避免溢出;然后,您可以将结果与值INT_MIN
和INT_MAX
进行比较,如果超出范围,则采取适当的纠正措施。但int
和long 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;