2015-09-20 204 views
3

因此,這似乎很容易,但無論是我想的東西或... ...有沒有辦法做到這一點..如何實現無符號abs(int)?

首先嚐試:?

unsigned abs(int value) { return value < 0 ? -value : value; } 

不,「值」是UB 。這是通過clang -sanitize檢測到的,在面對積極的優化時通常是不安全的(儘管我真的希望沒有一個理智的編譯器濫用這個)。

好的。讓我們投射到未簽名!

unsigned abs(int value) { return value < 0 ? -unsigned(value) : unsigned(value); } 

不,這會導致MSVC中出現C4146警告。另外,由於定義了無符號值的一元減號,我認爲這對於有符號整數採用了一種雙補碼整數格式。

好吧......

unsigned abs(int value) { return value < 0 ? ~unsigned(value) + 1 : unsigned(value); } 

這似乎並沒有產生任何警告或不確定的行爲,但當然只適用於兩互補整數。此外,它有點模糊 - 需要一個評論,解釋了爲什麼這不是直接使用的東西...

實際上是否可以實現上述功能,而不觸發UBs或依賴整數表示?請告訴我的答案是「是」之前,我失去C.

+0

你是否將有符號整數轉換爲無符號整數或者是否需要'abs'函數將'unsigned int'作爲參數? –

+0

0-val代替-val怎麼樣? '無符號abs(int值){返回值<0? 0值:值; }' –

+3

既然'INT_MIN'是一個邊緣情況,你可以明確地處理它。這很清楚你處理邊緣情況。 – chris

回答

1

正確的做法是#2,但沉默MSVC警告一種解決方法需要應用:

unsigned abs(int value) { return value < 0 ? 0 - unsigned(value) : unsigned(value); } 

原因這是正確的是,簽署到無符號轉換定義爲返回2^N + v爲負v;對於無符號整數,一元減號定義爲2^N-v;因此無論有符號整數表示,此代碼都會正確返回絕對值。

1

如果-value可能會導致不確定的行爲的所有剩餘的希望那麼這應該是明確的:

unsigned abs(int value) { return value < 0 ? 0-value : value; }