Tre*_*ith 8 c++ floating-point templates boost integer-overflow
我正在做一堆应用数学/信号处理/算法 C++ 代码。
我已启用-Wconversion编译器警告以捕获诸如类型double到类型数字的运行时转换之类的问题int32_t。
显然,在这些转换过程中我总是很担心,因为:
int32_t在本例中))每当我担心这种转换时,我通常使用单行检查:
boost::numeric_cast<DestType>(SourceType)
Run Code Online (Sandbox Code Playgroud)
但是,我想在没有boost.
直接的 C++ 有等价的boost::numeric_cast<DestType>(SourceType)吗?
如果直接的 C++ 没有等价物,那么什么是可比较的非boost实现?
我认为有点类似的检查基本上是一个模板函数,它有一个 if 语句来检查输入参数是否正溢出或负溢出(通过使用std::numeric_limits<DestType> ::max()and::min()和引发异常)。
正如 @SergeyA 所说,标准 C++ 规范目前没有与 Boost 等效的规范boost::numeric_cast<typename Destination>(Source value)。
这是一个仅使用标准 C++ 的直接实现:
template<typename Dst, typename Src>
inline Dst numeric_cast(Src value)
{
typedef std::numeric_limits<Dst> DstLim;
typedef std::numeric_limits<Src> SrcLim;
const bool positive_overflow_possible = DstLim::max() < SrcLim::max();
const bool negative_overflow_possible =
SrcLim::is_signed
or
(DstLim::lowest() > SrcLim::lowest());
// unsigned <-- unsigned
if((not DstLim::is_signed) and (not SrcLim::is_signed)) {
if(positive_overflow_possible and (value > DstLim::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": positive overflow"));
}
}
// unsigned <-- signed
else if((not DstLim::is_signed) and SrcLim::is_signed) {
if(positive_overflow_possible and (value > DstLim::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": positive overflow"));
}
else if(negative_overflow_possible and (value < 0)) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": negative overflow"));
}
}
// signed <-- unsigned
else if(DstLim::is_signed and (not SrcLim::is_signed)) {
if(positive_overflow_possible and (value > DstLim::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": positive overflow"));
}
}
// signed <-- signed
else if(DstLim::is_signed and SrcLim::is_signed) {
if(positive_overflow_possible and (value > DstLim::max())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": positive overflow"));
} else if(negative_overflow_possible and (value < DstLim::lowest())) {
throw std::overflow_error(__PRETTY_FUNCTION__ +
std::string(": negative overflow"));
}
}
// limits have been checked, therefore safe to cast
return static_cast<Dst>(value);
}
Run Code Online (Sandbox Code Playgroud)
笔记:
std::numeric_limits<float>::min()但必须使用std::numeric_limits<Dst>::lowest(),因为::min返回的是 1e-38 而不是负浮点值std::numeric_limits都是 const 表达式,因此编译器将能够在编译时大大简化它(即,N 个 if 语句将在编译时减少为一个 if 语句或没有)