2013-02-24 68 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