我只能使用这些操作! 〜& ^! +<< >>,我在抓住溢出时遇到问题,可以使用任何提示或帮助!
答案 0 :(得分:0)
取决于数字是签名还是未签名。
如果两个操作数都是无符号的,则溢出将回绕到0.
如果一个或两个操作数都被签名,则行为是实现定义的,但是大多数实现表示2的补码中的有符号整数,因此在这些情况下,正溢出将回绕到负端,并且负溢出将换行好的一面。
在无符号溢出的情况下,结果将少于至少一个操作数,因此您可以这样测试:
if ((x + y < x) || (x + y < y) {
printf("overflow\n");
}
在已签名的案例中,您首先需要检查两者是否为正(并检查否定回绕)或两者均为否定(并检查正向回绕):
if ((x > 0) && (y > 0) && ((x + y < x) || (x + y < y))) {
printf("negative overflow\n");
}
if ((x < 0) && (y < 0) && ((x + y > x) || (x + y > y))) {
printf("positive overflow\n");
}
正如我之前提到的,已签名的案例是实现定义的,只有当有符号整数表示为2的补码时,上述内容才有效。然而,在实践中,通常会出现这种情况。
这应该可以让您了解溢出的工作原理,尽管它并不仅仅使用您提到的特定运算符。有了这个,你应该能够弄清楚如何使用其他运算符来实现上面的表达式。
答案 1 :(得分:0)
使用有符号整数数学,除非您可以访问INT_MAX INT_MIN
之类的限制,否则无答案会解决未定义的行为。
#include <limits.h>
int is_overflow_add_signed(int a, int b) {
// This uses -, so does not meet OP's goal.
// Available as a guide
return (a < 0) ? (b < INT_MIN - a) : (b > INT_MAX - a);
}
使用无符号数学,只需查看结果&#34; wrap&#34;周围。
int is_overflow_add_unsigned(unsigned a, unsigned b) {
return (a + b) < a;
}
答案 2 :(得分:-1)
正如许多人所指出的那样,签署是不对的...... 所以我先把它更改为无符号。
您需要逐个计算。
由于您没有告诉我们数据类型,我认为它是4字节无符号数据。
unsigned long x, unsigned long y;
// x = ...
// y = ...
unsigned long first_byte_x = (x & 0xFF000000) >> 24;
unsigned long first_byte_y = (y & 0xFF000000) >> 24;
unsigned long other_bytes_x = x & 0x00FFFFFF;
unsigned long other_bytes_y = y & 0x00FFFFFF;
unsigned long other_bytes_sum = other_bytes_x + other_bytes_y;
unsigned long carry = (other_bytes_sum & 0xFF000000) >> 24;
unsigned long first_byte_sum = first_byte_x + first_byte_y + carry;
if (first_byte_sum > 0xFF)
// overflow
else
// not overflow
如果你可以使用mod(%),那么它会更简单。
*看起来像是一个家庭作业,所以我希望你在考虑之前就考虑过了......