Is there a standard sign function (signum, sgn) in

2018-12-31 14:46发布

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.

标签: c++ c math
24条回答
柔情千种
2楼-- · 2018-12-31 15:27

I ran into this just today. So fine, there's no standard way but...

Since the OP just needed to magnify the output range and re-centre it on 0, (-1 to 1 not 0 to 1) why not just double it and subtract 1?

I used this:

(x<0)*2-1

Or, forcing a bit shift:

(x<0)<<1-1

But the compiler will likely optimize that anyway.

查看更多
孤独总比滥情好
3楼-- · 2018-12-31 15:29

While the integer solution in the accepted answer is quite elegant it bothered me that it wouldn't be able to return NAN for double types, so I modified it slightly.

template <typename T> double sgn(T val) {
    return double((T(0) < val) - (val < T(0)))/(val == val);
}

Note that returning a floating point NAN as opposed to a hard coded NAN causes the sign bit to be set in some implementations, so the output for val = -NAN and val = NAN are going to be identical no matter what (if you prefer a "nan" output over a -nan you can put an abs(val) before the return...)

查看更多
不流泪的眼
4楼-- · 2018-12-31 15:31

Is there a standard sign function (signum, sgn) in C/C++?

Yes, depending on definition.

C99 and later has the signbit() macro in <math.h>

int signbit(real-floating x);
The signbit macro returns a nonzero value if and only if the sign of its argument value is negative. C11 §7.12.3.6


Yet OP wants something a little different.

I want a function that returns -1 for negative numbers and +1 for positive numbers. ... a function working on floats.

#define signbit_p1_or_n1(x)  ((signbit(x) ?  -1 : 1)

Deeper:

The post is not specific in the following cases, x = 0.0, -0.0, +NaN, -NaN.

A classic signum() returns +1 on x>0, -1 on x>0 and 0 on x==0.

Many answers have already covered that, but do not address x = -0.0, +NaN, -NaN. Many are geared for an integer point-of-view that usually lacks Not-a-Numbers (NaN) and -0.0.

Typical answers function like signnum_typical() On -0.0, +NaN, -NaN, they return 0.0, 0.0, 0.0.

int signnum_typical(double x) {
  if (x > 0.0) return 1;
  if (x < 0.0) return -1;
  return 0;
}

Instead, propose this functionality: On -0.0, +NaN, -NaN, it returns -0.0, +NaN, -NaN.

double signnum_c(double x) {
  if (x > 0.0) return 1.0;
  if (x < 0.0) return -1.0;
  return x;
}
查看更多
姐姐魅力值爆表
5楼-- · 2018-12-31 15:32

I don't know of a standard function for it. Here's an interesting way to write it though:

(x > 0) - (x < 0)

Here's a more readable way to do it:

if (x > 0) return 1;
if (x < 0) return -1;
return 0;

If you like the ternary operator you can do this:

(x > 0) ? 1 : ((x < 0) ? -1 : 0)
查看更多
裙下三千臣
6楼-- · 2018-12-31 15:32

Apparently, the answer to the original poster's question is no. There is no standard C++ sgn function.

查看更多
呛了眼睛熬了心
7楼-- · 2018-12-31 15:32

It seems that most of the answers missed the original question.

Is there a standard sign function (signum, sgn) in C/C++?

Not in the standard library, but there is in boost, which might as well be part of the standard.

    #include <boost/math/special_functions/sign.hpp>

    //Returns 1 if x > 0, -1 if x < 0, and 0 if x is zero.
    template <class T>
    inline int sign (const T& z);

http://www.boost.org/doc/libs/1_47_0/libs/math/doc/sf_and_dist/html/math_toolkit/utils/sign_functions.html

查看更多
登录 后发表回答