2016-02-05 70 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; 
} 
相關問題