c ++有一个等价的boost :: numeric_cast <desttype>(SourceType)?

时间:2018-04-04 18:40:28

标签: c++ templates boost floating-point integer-overflow

我正在做一堆应用数学/信号处理/算法C ++代码。

我已启用-Wconversion编译器警告,以捕获类型为double的数字的运行时转换以及int32_t类型的问题。

显然,在这些转换过程中我总是担心,因为:

  • 丢失数字十进制值
  • 可能是正溢出或负溢出(“正溢出”是指double的值大于INT32_MAX并尝试将该值存储在目标类型中(在这种情况下为int32_t))

每当我担心这种转换时,我通常会使用单行检查:

boost::numeric_cast<DestType>(SourceType)

但是我想在没有boost的情况下做同样的事情。

直接C ++是否具有等效的boost::numeric_cast<DestType>(SourceType)

如果直接C ++没有等效的,那么实施的非boost是什么?

我认为一个有点类似的检查基本上是一个模板函数,它有一个if语句来检查输入参数是否存在正溢出或负溢出(使用std::numeric_limits<DestType> ::max()和{{1并抛出异常)。

1 个答案:

答案 0 :(得分:1)

https://developers.google.com/identity/sign-in/web/devconsole-project,目前没有标准C ++规范与Boost的boost::numeric_cast<typename Destination>(Source value)等效。

这是一个只使用标准C ++的直接实现:

template<typename Dst, typename Src>
inline Dst numeric_cast(Src value)
{
    const bool positive_overflow_possible = std::numeric_limits<Dst>::max() < std::numeric_limits<Src>::max();
    const bool negative_overflow_possible =
            std::numeric_limits<Src>::is_signed
            or
            (std::numeric_limits<Dst>::lowest() > std::numeric_limits<Src>::lowest());

    // unsigned <-- unsigned
    if((not std::numeric_limits<Dst>::is_signed) and (not std::numeric_limits<Src>::is_signed)) {
        if(positive_overflow_possible and (value > std::numeric_limits<Dst>::max())) {
            throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": positive overflow"));
        }
    }
    // unsigned <-- signed
    else if((not std::numeric_limits<Dst>::is_signed) and std::numeric_limits<Src>::is_signed) {
        if(positive_overflow_possible and (value > std::numeric_limits<Dst>::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(std::numeric_limits<Dst>::is_signed and (not std::numeric_limits<Src>::is_signed)) {
        if(positive_overflow_possible and (value > std::numeric_limits<Dst>::max())) {
            throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": positive overflow"));
        }
    }
    // signed <-- signed
    else if(std::numeric_limits<Dst>::is_signed and std::numeric_limits<Src>::is_signed) {
        if(positive_overflow_possible and (value > std::numeric_limits<Dst>::max())) {
            throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": positive overflow"));
        } else if(negative_overflow_possible and (value < std::numeric_limits<Dst>::lowest())) {
            throw std::overflow_error(__PRETTY_FUNCTION__ + std::string(": negative overflow"));
        }
    }

    // limits have been checked, therefore safe to cast
    return static_cast<Dst>(value);
}

注释:

  • 编译器是g ++版本4.8.5。
  • 编译器标志:
    • -std =的C ++ 0x
    • -O0
    • -g3
    • -pedantic
    • -pedantic-错误
    • -Wall
    • -Wextra
    • -Werror
    • -Wconversion
    • -c
    • -fmessage长度= 0
    • -Wsign转换
    • -fPIC
    • -MMD
    • -MP
  • 对于浮点类型,您无法使用std::numeric_limits<float>::min(),而必须使用std::numeric_limits<Dst>::lowest(),因为::min返回的是1e-38而不是负浮点值
  • 很多std::numeric_limits都是const表达式,因此编译器将能够在编译时大大简化这一点(即N if语句将在编译时减少为一个if语句或者没有)