2016-02-05 71 views
-1

我只能使用操作! 〜& ^! + < < >>,我无法抓住溢出,可以使用任何提示或帮助!如何确定我是否可以计算x + y而不溢出C?

+0

不能使用'-'? – user3386109

+3

这是一个相当不错的家庭作业问题,但过于宽泛,因为堆栈溢出不是教程网站。你必须解决你自己。只是:假设你必须使用带符号的整数类型,你必须在发生**之前捕获溢出**,否则所有投注都关闭。所以你必须检查组合操作数是否会超出界限。提示:您必须使用limits.h并认为“溢出”实际上意味着什么。每个操作员都有所不同。 – Olaf

+0

[如何检测C/C++中的整数溢出?](http:// stackoverflow。com/q/199333/995714) –

回答

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的补码。然而在实践中,这通常是这种情况。

这应该给你的溢出是如何工作的想法,虽然它并不只使用你提到的具体运营。有了这个,你应该能够弄清楚如何使用其他操作符来实现上述表达式。

+0

“未定义行为的一个示例是整数溢出行为。” C11dr§3.4.33.这是C规范中未定义行为的第一个示例。它不是实现定义的,但是UB .. – chux

+0

不同意“如果一个...操作数被签名,行为就是实现定义的,”如果一个操作数是'signed int'而另一个是'unsigned int','signed int'值将被转换为'unsigned int',这是一个定义良好的转换。这导致定义良好的'unsigned' +'unsigned'。 – chux

+0

'if((x> 0)&&(y> 0)&&((x + y 0',***将假设'x + y immibis

-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(%),那么它会更简单。

*它看起来像一个家庭作业,所以我希望你认为你的提问前足......

+0

不需要这样做。对于无符号类型只是't = x + y;溢出= t

+0

对于'x = -1,y = -1'和其他很多失败。 – chux

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); 
} 

用无符号数学,只要看看结果是否“包裹”了。

int is_overflow_add_unsigned(unsigned a, unsigned b) { 
    return (a + b) < a; 
} 
相关问题