我正在尝试利用 errno
来检测是否执行了导致溢出的操作。然而,虽然我编写了一个故意造成溢出的函数,但 errno == ERANGE
是错误的。这是怎么回事?
以下是代码:
#include <stdio.h>
#include <errno.h>
int main(int argc, char* argv[]) {
unsigned char c = 0;
int i;
for (i = 0; i< 300; i++) {
errno = 0;
c = c + 1;
if (errno == ERANGE) {// we have a range error
printf("Overflow. c = %u\n", c);
} else {
printf("No error. c = %u\n", c);
}
}
return 0;
}
我原本期望在将255加1的时候会出现溢出错误,但是却没有出现。以下是(截取的)输出结果:
No error. c = 245
No error. c = 246
No error. c = 247
No error. c = 248
No error. c = 249
No error. c = 250
No error. c = 251
No error. c = 252
No error. c = 253
No error. c = 254
No error. c = 255
No error. c = 0
No error. c = 1
No error. c = 2
No error. c = 3
No error. c = 4
No error. c = 5
No error. c = 6
No error. c = 7
No error. c = 8
No error. c = 9
有人能解释一下为什么它没有检测到错误,以及我要如何更改它或制作一个可以检测是否溢出的函数吗?请注意:最终我想使用
long int
来做这件事,所以不能简单地将它转换为更大的数据类型。编辑:
我后来找到了一些简单的函数,可以分别检测整数数据类型的加法和乘法溢出。虽然它并不涵盖所有情况,但它涵盖了很多情况。
乘法:
int multOK(long x, long y)
/* Returns 1 if x and y can multiply without overflow, 0 otherwise */
{
long p = x*y;
return !x || p/x == y;
}
有符号数加法:
int addOK(long x, long y)
/* Returns 1 if x and y can add without overflow, 0 otherwise */
{
long sum = x+y;
int neg_over = (x < 0) && (y < 0) && (sum >= 0);
int pos_over = (x >= 0) && (y >= 0) && (sum < 0);
return !neg_over && !pos_over;
}
无符号加法:
int unsignedAddOK(unsigned long x, unsigned long y)
/* Returns 1 if x and y can add without overflow, 0 otherwise */
{
unsigned long sum = x+y;
return sum > x && sum > y;
}
strtod
)会设置errno。 - jedwards<limits.h>
可能会有所帮助,以及 这个相关问题。 - jedwardschecked
的C#),或者一种透明支持任意精度算术的语言(例如Python,Lisp,Haskell等)。 - Dietrich Epp