假设我已经声明了以下变量:
some_dataType a,b,c; //a,b,c are positive
int res;
res=a+b-c;
并且我已经获得了变量 res
不能跨越整数限制的信息 . 为了避免从 a+b-c
中的表达式 a+b
溢出,我有以下选项 -
-
将a,b,c声明为long int
-
(a-c)
b -
(long int)
(a b-c)//或其他类型的投射
我的问题是以上哪项是好的做法 . 另外,为了摆脱这一切,我更喜欢做选项1.但它可能会增加程序的内存大小(虽然不适用于此程序,但适用于大型应用程序) .
假设:long int大于int谢谢@Retired Ninja
2 回答
没有简单,通用,可移植的方法来避免整数溢出 .
使用更宽的整数类型不是一般解决方案,因为
int
和long
类型在某些系统上的大小相同's no guarantee that there is a wider integer type. It' . 32位系统通常会产生int
和long
32位;甚至一些64位系统也做同样的事情 . 一些64位系统同时生成int
和long
64位 .你写了:
最好小心术语 . 虽然类型名称
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
,则添加是安全的 .我不保证以上内容是完全正确的*我只是把它写在了我的头顶上),但在大多数情况下,它可能比它的 Value 更多的努力 .
信任但要验证: