from.. 2009-12-14 22:27 采纳率: 100%
浏览 1440
已采纳

C / c + + 中是否有标准符号函数(signum,sgn)?

I want a function that returns -1 for negative numbers and +1 for positive numbers. http://en.wikipedia.org/wiki/Sign_function It's easy enough to write my own, but it seems like something that ought to be in a standard library somewhere.

Edit: Specifically, I was looking for a function working on floats.

转载于:https://stackoverflow.com/questions/1903954/is-there-a-standard-sign-function-signum-sgn-in-c-c

  • 写回答

23条回答 默认 最新

  • bug^君 2011-01-05 22:19
    关注

    Surprised no one has posted the branchless, type-safe C++ version yet:

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

    Benefits:

    • Actually implements signum (-1, 0, or 1). Implementations here using copysign only return -1 or 1, which is not signum. Also, some implementations here are returning a float (or T) rather than an int, which seems wasteful.
    • Works for ints, floats, doubles, unsigned shorts, or any custom types constructible from integer 0 and orderable.
    • Fast! copysign is slow, especially if you need to promote and then narrow again. This is branchless and optimizes excellently
    • Standards-compliant! The bitshift hack is neat, but only works for some bit representations, and doesn't work when you have an unsigned type. It could be provided as a manual specialization when appropriate.
    • Accurate! Simple comparisons with zero can maintain the machine's internal high-precision representation (e.g. 80 bit on x87), and avoid a premature round to zero.

    Caveats:

    • It's a template so it'll take forever to compile.
    • Apparently some people think use of a new, somewhat esoteric, and very slow standard library function that doesn't even really implement signum is more understandable.
    • The < 0 part of the check triggers GCC's -Wtype-limits warning when instantiated for an unsigned type. You can avoid this by using some overloads:

      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>());
      }
      

      (Which is a good example of the first caveat.)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(22条)

报告相同问题?

悬赏问题

  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用