今天做了一个实验,就是对一些数据的边界进行测试,结果竟然抛异常终止了。
这有点出乎我的意料,因为并不是除0错,我以为会忽略溢出呢。后来看了资料,才明白是怎么回事。
首先,32bit整数的表达范围是 -2147483648 ~ 2147483647,我们可以看到INT_MIN的定义是( - 2147483647 - 1 ),据《深入理解计算机系统》里面讲述,这是因为将一个字符串解析成数字,如果是这样:
int parse_int( char* str ) { int sign = 0, ans = 0; if( *str == '-' ) { ++str; sign = 1; } while( '0' <= *str && *str <= '9' ) { ans = ans * 10 + *str++ - '0'; } return sign ? -ans : ans; }
但是我们也知道,有一些加减法或乘法溢出,是不会报错的,甚至我们还利用了这个特点做一些运算。但是今天我遇到了一个除法出错的情况。
int x, y; std::cin >> x >> y; std::cout << (x / y) << std::endl;
实际上,C语言中,对于有符号整型运算的溢出是未定义的行为,而无符号整数则将溢出的部分舍去,取结果的低位部分作为结果。(In the C programming language, signed integer overflow causes undefined behavior, while unsigned integer overflow causes the number to be reduced modulo a power of two, meaning that unsigned integers "wrap around" on overflow.)
另外就是Linux中的信号有一个是SIGFPE,当执行算术运算出错时抛出,例如除0错。看字面意思是Floating-Point Error才对,可是整型确实也用到了它。
http://en.wikipedia.org/wiki/Integer_overflow
http://en.wikipedia.org/wiki/SIGFPE#SIGFPE