【问题标题】:boost::multiprecision::cpp_dec_float_50 overflow checkingboost::multiprecision::cpp_dec_float_50 溢出检查
【发布时间】:2013-09-10 20:09:12
【问题描述】:

我正在尝试将 boost::multiprecision 库用于浮点(或在这种情况下为定点)点算术。 但是,我无法通过以下方式检测潜在的溢出:

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;

不应该为触发异常的类型在 max() 中加 1 吗? 我也检查了溢出后的底层类型,不是cpp_dec_float_inf,还是cpp_dec_float_finite。 此外,dtNew 的值等于 std::numeric_limits::max()

我在这里是不是完全被概念误解了?如果是这样,防止 boost::multiprecision::cpp_dec_float 溢出的正确方法是什么?

【问题讨论】:

    标签: c++ boost floating-point overflow numeric-limits


    【解决方案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;
    }
    

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

    我的印象是该类型被实现为定点(我知道这个名字很愚蠢),但事实并非如此。 这是来自提升doc

    涉及 cpp_dec_float 的操作总是被截断。但是请注意,由于它们实际上是保护数字,因此实际上这对大多数用例的准确性没有实际影响。

    多精度库似乎没有固定精度类型。

    但是,为了检查 cpp_dec_float 中的溢出,可以这样做:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-08
      • 2017-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多