boost::multiprecision::cpp_dec_float_50 overflow checking

℡╲_俬逩灬. 提交于 2019-12-11 04:36:32

问题


I am trying to use the boost::multiprecision library for floating (or in that case, fixed) point arithmetic. However, I am having trouble detecting potential overflow in the following way:

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;

Shouldn't even adding 1 to max() for the type trigger the throw of the exception? I have also checked the underlying type after the overflow, and it's not cpp_dec_float_inf, still cpp_dec_float_finite. Also, the value of dtNew is equal to std::numeric_limits::max()

Am I under a complete conceptual misapprehension here? If so, what would be the correct way to prevent a boost::multiprecision::cpp_dec_float<50> from overflowing?


回答1:


Ok, I have debugged into the library, and the "error" happens on this line:

// 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;
}

Adding 1 to the numeric_limit of the type is negligible, so the addition is discarded. Hence it is not >=.

I was under the impression that the type was implemented as fixed point (dumb considering the name, I know), which it is not. This is from the boost doc

Operations involving cpp_dec_float are always truncating. However, note that since their are guard digits in effect, in practice this has no real impact on accuracy for most use cases.

Bummer that the multiprecision library doesn't seem to have a fixed precision type.

However, in order to check for overflow in cpp_dec_float, one can do this:

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


来源:https://stackoverflow.com/questions/18727896/boostmultiprecisioncpp-dec-float-50-overflow-checking

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!