提高::多倍:: cpp_dec_float_50溢出检查(boost::multiprecisio

2019-10-18 14:51发布

我试图使用升压::多倍库浮动(或在这种情况下,固定)浮点运算。 但是,我有麻烦通过以下方式检测潜在溢出:

typedef boost::multiprecision::number<
                                      boost::multiprecision::cpp_dec_float<50>
                                     > flp_type;
typedef boost::multiprecision::number<
                                      boost::multiprecision::cpp_dec_float<100>
                                     > safe_flp_type;

flp_type _1 = std::numeric_limits<flp_type>::max();
flp_type _2("1");
flp_type _3 = std::numeric_limits<flp_type>::max();
flp_type dtNew;

// Here is the check
safe_flp_type _res = safe_flp_type(_1) + _2;

// **This condition is true for addition of _1 and _3,**
// but fails for _1 + _2
if(  (_res > std::numeric_limits<flp_type>::max())  // overflow
   ||(_res < std::numeric_limits<flp_type>::min())) // underflow
{
    BOOST_THROW_EXCEPTION(OverUnderflow() << SpecificErrInfo(L"Attempted floating point over/underflow"));
}

dtNew = _1 + _2;

甚至不应该加1,MAX()的类型触发异常抛出? 我还检查的基础类型溢出后,它不是cpp_dec_float_inf,仍然cpp_dec_float_finite。 另外,dtNew的值等于到std :: numeric_limits :: MAX()

我是这里下一个完整的概念误解? 如果是这样,这将是阻止一个boost ::多倍:: cpp_dec_float <50>溢出的正确方法是什么?

Answer 1:

好吧,我已经调试到库中,并在此行中的“错误”发生的情况:

// Check if the operation is out of range, requiring special handling.
if(v.iszero() || (ofs_exp > max_delta_exp))
{
   // Result is *this unchanged since v is negligible compared to *this.
   return *this;
}

加1的类型的numeric_limit是可忽略的,所以除被丢弃。 因此,它是不> =。

我的印象是,该类型被实现为固定点(哑考虑的名字,我知道),它不是。 这是从升压文档

涉及cpp_dec_float操作总是截断。 但是请注意,因为他们实际上是后卫数字,在实践中,这对大多数使用情况的精度没有实际影响。

无赖的多倍库似乎并不具有固定的精度类型。

然而,为了在cpp_dec_float检查溢出,可以这样做:

dtNew = _1 * _2;
if(dtNew.backend().isinf())
{
    BOOST_THROW_EXCEPTION(OverUnderflow() << SpecificErrInfo(L"Attempted floating point over/underflow"));
}


文章来源: boost::multiprecision::cpp_dec_float_50 overflow checking