2013-02-24 31 views
2

雖然std::abs(或::absÇ開發者)不提倡返回值,爲此不能處理std::numeric_limit<T>::min(),我想有一個abs實現,它確實更「安全」的處理。推動型ABS FPGA實現

template <typename T> 
typename std::make_unsigned<typename std::enable_if<std::is_signed<T>::value, T>::type>::type secure_abs(T value) { 
    if(value >= 0) 
     return value; 

    if(value == std::numeric_limits<T>::min()) 
     return *reinterpret_cast<typename std::make_unsigned<T>::type*>(&value); 

    return -value; //TODO: Prevent promotion to int 
} 

我還沒弄清楚的事情是如何防止升級到int(當刪除減號)後的轉換警告。

有沒有更優雅/正確的方法去除減號?

編輯:

現在應該是INT_MIN和2complement正確的。

+0

需要注意的是,呼籲INT_MIN這個功能是不確定的行爲,和gcc的最新版本可即使利用這個事實來破壞你的代碼。您需要在應用運算符之前將其轉換爲無符號,或者計算1-(值+1)。 – 2013-02-24 19:23:18

+0

「刪除減號」?我不明白。你爲什麼要刪除減號?整個功能就是「返回值」。那麼,不是嗎?你能詳細說明嗎? – 2013-02-24 19:45:42

+0

@ JohannesSchaub-litb:他的意思是* *號碼 – 2013-02-24 20:04:28

回答

0

由於類型推廣到int使用算術運算時類型的「等級」低於int我只看到2種方式如何克服這種警告是必然的:

  1. 複雜。 return adder(!value, 1);其中adder函數是一個 按位加法器。你可能會發現它是如何在硬件中實現的,並且你自己實現了一個。
  2. 簡單。 return static_cast<T>(-value)。既然你沒有這可能會導致溢出類型T的任何算術運算是絕對安全的「取消」推廣int
+0

對於2.促銷仍然通過減號,正確。所以演員們可能會沉默假陽性分析! – abergmeier 2013-02-25 09:39:10

+0

是的,它只是沉默編譯器。如果你使用任何算術運算,你別無選擇,只能保持沉默。還提到了另一種方法,但我認爲它不值得編寫自定義加法器 – ixSci 2013-02-25 09:52:54