问题

我想要一个返回-1的负数和+1的正数. http://en.wikipedia.org/wiki/Sign_function 写自己很容易,但似乎应该在某个地方的标准库中。

编辑:具体来说,我正在寻找一个在浮点数上工作的函数.

  最佳答案

惊讶没有人发布打字安全的C版本:

 template <typename T> int sgn(T val) {
    return (T(0) < val) - (val < T(0));
}
 

福利:

  • 实际上实现signum(-1,0或1).这里使用copysign的实现只返回-1或1,这不是signum.此外,这里的一些实现返回float(或T)而不是int,这似乎很浪费.
  • 适用于整数,浮点数,双打,无符号短裤,或从整数0和orderable构造的任何自定义类型。
  • 快!copysign很慢,特别是如果你需要提升,然后再缩小。
  • 符合标准! bitshift hack很简洁,但只适用于某些位表示,当您有一个无符号类型时不起作用.它可以酌情作为手动专业化提供.
  • 准确!简单的与零的比较可以保持机器的内部高精度表示(例如x87上的80位),并避免过早的回合到零。

警告:

  • 这是一个模板,因此在某些情况下编译可能需要更长时间。
  • 显然,一些人认为使用一个新的,有些更深奥的,非常缓慢的标准库功能,甚至没有真正实现标志更容易理解。
  • 当为无符号类型实例化时,检查的< 0部分触发GCC的-Wtype-limits警告.您可以通过使用一些超载来避免这种情况:

     template <typename T> inline constexpr
    int signum(T x, std::false_type is_signed) {
        return T(0) < x;
    }
    
    template <typename T> inline constexpr
    int signum(T x, std::true_type is_signed) {
        return (T(0) < x) - (x < T(0));
    }
    
    template <typename T> inline constexpr
    int signum(T x) {
        return signum(x, std::is_signed<T>());
    }
     

    (这是第一个警告的好例子)

  相同标签的其他问题

c++cmath