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

编辑:具体来说,我正在寻找一个函数工作在浮动。


当前回答

有一种不用分支的方法,但不太好。

sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));

http://graphics.stanford.edu/~seander/bithacks.html

那一页上还有很多其他有趣的、过于聪明的东西……

其他回答

有点跑题了,但我用了这个:

template<typename T>
constexpr int sgn(const T &a, const T &b) noexcept{
    return (a > b) - (a < b);
}

template<typename T>
constexpr int sgn(const T &a) noexcept{
    return sgn(a, T(0));
}

我发现第一个函数-有两个参数的函数,比“标准”sgn()更有用,因为它最常在这样的代码中使用:

int comp(unsigned a, unsigned b){
   return sgn( int(a) - int(b) );
}

vs.

int comp(unsigned a, unsigned b){
   return sgn(a, b);
}

无符号类型没有强制转换,也没有额外的减号。

这段代码是用sgn()写的

template <class T>
int comp(const T &a, const T &b){
    log__("all");
    if (a < b)
        return -1;

    if (a > b)
        return +1;

    return 0;
}

inline int comp(int const a, int const b){
    log__("int");
    return a - b;
}

inline int comp(long int const a, long int const b){
    log__("long");
    return sgn(a, b);
}

我的《C in a Nutshell》揭示了一个叫做copysign的标准函数的存在,它可能很有用。看起来,copyysign(1.0, -2.0)将返回-1.0,而copyysign(1.0, 2.0)将返回+1.0。

很接近吧?

这个问题很老了,但现在有了这种理想函数。我用not, left shift和dec添加了一个包装器。

您可以使用C99中基于signbit的包装器函数来获得确切的期望行为(请参阅下面的代码)。

返回x的符号是否为负。 这也可以应用于无穷大,nan和零(如果零是无符号的,它被认为是正的

#include <math.h>

int signValue(float a) {
    return ((!signbit(a)) << 1) - 1;
}

注意:我使用operand not("!")是因为符号位的返回值没有指定为1(即使例子让我们认为它总是这样),但对于负数是真的:

返回值 如果x的符号为负,则为非零值(true);否则为零(false)。

然后我左移乘以2(“<< 1”),这将给我们一个正数2,一个负数0,最后减去1,分别得到1和-1的正数和负数,这是OP要求的。

有一种不用分支的方法,但不太好。

sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));

http://graphics.stanford.edu/~seander/bithacks.html

那一页上还有很多其他有趣的、过于聪明的东西……

显然,最初的帖子的问题的答案是否定的。没有标准的c++ sgn函数。