c++ - 如何在模板中定义浮点常量。避免在运行时强制转换

标签 c++ c++11 numerical-methods numerical

假设我有一个简单的函数可以做这样的事情:

template<typename T>
T get_half(T a){
    return 0.5*a;
}

这个函数通常会用 T 为 double 或 float 来计算。 该标准规定 0.5 将是 double (0.5f 表示 float )。 如何编写上面的代码,使 0.5 始终为 T 类型,以便在计算产品或返回时不进行强制转换? 我想要的是 0.5 在编译时成为 T 类型的常量。这个问题的重点是我想避免在运行时进行转换。

例如,如果我写:

template<typename T>
T get_half(T a){
    return T(0.5)*a;
}

我能绝对确定 T(0.5) 在编译时求值吗? 如果没有,实现这一目标的正确方法是什么?如果需要,我可以使用 c++11。

提前谢谢你。

在 c++11 中,我有一个 numeric_traits 类,如下所示(在头文件中)

template<typename Scalar>
struct numeric_traits{
    static constexpr Scalar one_half = 0.5;
    //Many other useful constants ....
};

所以在我的代码中,我会将其用作:

template<typename T>
T get_half(T a){
    return numeric_traits<T>::one_half*a;
}

这就是我想要的,即 0.5 在编译时以我需要的精度解析,并且在运行时没有发生转换。但是缺点是:

  • 每次需要新常量时我都需要修改 numeric_traits
  • 语法可能太冗长烦人了? (当然,这真的不是什么大问题)
  • 如果有类似这样的东西会很好:constant(0.5) 在运行时解析为 T 类型。

再次感谢您。

最佳答案

没有也不可能有任何方法强制常量在运行时永远不被计算,因为有些机器根本没有可以加载类型的所有可能值的单一指令。例如,机器可能只有一个 16 位加载常量指令,其中 0x12345678 需要在运行时计算为 0x1234 << 16 | 0x5678 。或者,可以从内存中加载这样一个常量,但这可能是比计算它成本更高的操作。

你需要稍微相信你的编译器。在可行的系统上,任何具有任何优化量的编译器都将以与翻译 T(0.5) 相同的方式翻译 0.5f ,假设 Tfloat0.5f 将以最适合您的平台的方式计算。这可能涉及将其作为常量加载,或者可能涉及计算它。或者谁知道呢,您的编译器可能会将 T(0.5)*a 更改为 a/2,如果结果相同的话。

在您的问题中,您举了一个添加 numeric_traits 帮助程序类的示例。 IMO,这太过分了。在 constexpr 产生影响的极不可能的情况下,您可以只写

template <typename T>
T get_half(T a) {
    constexpr T half = 0.5;
    return half * a;
}

但是,在我看来,这仍然弊大于利:您的 get_half 现在不能再用于非文字类型。它要求类型支持从常量表达式中的 double 转换。假设您有一个任意精度的 rational 类型,在编写时没有考虑到 constexpr。现在您的 get_half 无法使用,因为初始化 constexpr T half = 0.5; 无效,即使 0.5 * a 可能已经编译。

即使您的 numeric_traits 辅助类也是如此;它不是因为我将它移动到函数体中而无效。

关于c++ - 如何在模板中定义浮点常量。避免在运行时强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28384981/

相关文章:

c++ - 当你的函数名称和输入后有 "const"时,这意味着什么?

c++ - 关于 C++ 中的 "bind"

c++ - 函数指针声明在 C 中有效,但在 C++ 中无效

c++ - 使用 gcc 的本地拷贝进行编译,不兼容 libstdc++

python - 如何在 python 中权衡具有高斯分布的 2 个变量的函数?

r - 哪些数值优化器可以只使用梯度,而没有明确的目标值?

c++ - 64位指针的无锁内存回收

c++ - 将 CryptoPP::Integer 类型转换为 int

c++ - 为 C 消费包装 C++ 类 API

python - 使用 while 循环的龙格库塔算法