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












350















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.










share|improve this question




















  • 9





    What should it return for 0?

    – Craig McQueen
    Dec 14 '09 at 23:26






  • 51





    @Craig McQueen; that depends on if it is a positive zero or negative zero.

    – ysth
    Dec 15 '09 at 5:53






  • 1





    I noticed that you specified the return value as an integer. Are you looking for a solution that takes integers or floating point numbers?

    – Mark Byers
    Dec 15 '09 at 9:56






  • 4





    @ysth @Craig McQueen, false for floats too, no? sgn(x)'s definition says to return 0 if x==0. According to IEEE 754, negative zero and positive zero should compare as equal.

    – RJFalconer
    Jun 4 '14 at 11:28








  • 4





    @ysth "it depends on positive zero or negative zero". In fact, it does not.

    – RJFalconer
    Jun 6 '14 at 8:10
















350















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.










share|improve this question




















  • 9





    What should it return for 0?

    – Craig McQueen
    Dec 14 '09 at 23:26






  • 51





    @Craig McQueen; that depends on if it is a positive zero or negative zero.

    – ysth
    Dec 15 '09 at 5:53






  • 1





    I noticed that you specified the return value as an integer. Are you looking for a solution that takes integers or floating point numbers?

    – Mark Byers
    Dec 15 '09 at 9:56






  • 4





    @ysth @Craig McQueen, false for floats too, no? sgn(x)'s definition says to return 0 if x==0. According to IEEE 754, negative zero and positive zero should compare as equal.

    – RJFalconer
    Jun 4 '14 at 11:28








  • 4





    @ysth "it depends on positive zero or negative zero". In fact, it does not.

    – RJFalconer
    Jun 6 '14 at 8:10














350












350








350


107






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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 24 '09 at 2:40







batty

















asked Dec 14 '09 at 22:27









battybatty

3,06492630




3,06492630








  • 9





    What should it return for 0?

    – Craig McQueen
    Dec 14 '09 at 23:26






  • 51





    @Craig McQueen; that depends on if it is a positive zero or negative zero.

    – ysth
    Dec 15 '09 at 5:53






  • 1





    I noticed that you specified the return value as an integer. Are you looking for a solution that takes integers or floating point numbers?

    – Mark Byers
    Dec 15 '09 at 9:56






  • 4





    @ysth @Craig McQueen, false for floats too, no? sgn(x)'s definition says to return 0 if x==0. According to IEEE 754, negative zero and positive zero should compare as equal.

    – RJFalconer
    Jun 4 '14 at 11:28








  • 4





    @ysth "it depends on positive zero or negative zero". In fact, it does not.

    – RJFalconer
    Jun 6 '14 at 8:10














  • 9





    What should it return for 0?

    – Craig McQueen
    Dec 14 '09 at 23:26






  • 51





    @Craig McQueen; that depends on if it is a positive zero or negative zero.

    – ysth
    Dec 15 '09 at 5:53






  • 1





    I noticed that you specified the return value as an integer. Are you looking for a solution that takes integers or floating point numbers?

    – Mark Byers
    Dec 15 '09 at 9:56






  • 4





    @ysth @Craig McQueen, false for floats too, no? sgn(x)'s definition says to return 0 if x==0. According to IEEE 754, negative zero and positive zero should compare as equal.

    – RJFalconer
    Jun 4 '14 at 11:28








  • 4





    @ysth "it depends on positive zero or negative zero". In fact, it does not.

    – RJFalconer
    Jun 6 '14 at 8:10








9




9





What should it return for 0?

– Craig McQueen
Dec 14 '09 at 23:26





What should it return for 0?

– Craig McQueen
Dec 14 '09 at 23:26




51




51





@Craig McQueen; that depends on if it is a positive zero or negative zero.

– ysth
Dec 15 '09 at 5:53





@Craig McQueen; that depends on if it is a positive zero or negative zero.

– ysth
Dec 15 '09 at 5:53




1




1





I noticed that you specified the return value as an integer. Are you looking for a solution that takes integers or floating point numbers?

– Mark Byers
Dec 15 '09 at 9:56





I noticed that you specified the return value as an integer. Are you looking for a solution that takes integers or floating point numbers?

– Mark Byers
Dec 15 '09 at 9:56




4




4





@ysth @Craig McQueen, false for floats too, no? sgn(x)'s definition says to return 0 if x==0. According to IEEE 754, negative zero and positive zero should compare as equal.

– RJFalconer
Jun 4 '14 at 11:28







@ysth @Craig McQueen, false for floats too, no? sgn(x)'s definition says to return 0 if x==0. According to IEEE 754, negative zero and positive zero should compare as equal.

– RJFalconer
Jun 4 '14 at 11:28






4




4





@ysth "it depends on positive zero or negative zero". In fact, it does not.

– RJFalconer
Jun 6 '14 at 8:10





@ysth "it depends on positive zero or negative zero". In fact, it does not.

– RJFalconer
Jun 6 '14 at 8:10












23 Answers
23






active

oldest

votes


















446














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.)








share|improve this answer





















  • 16





    @GMan: GCC only just now (4.5) stopped having cost quadratic to the number of instantiations for template functions, and they are still drastically more expensive to parse and instantiate than manually written functions or the standard C preprocessor. The linker also has to do more work to remove duplicate instantiations. Templates also encourage #includes-in-#includes, which makes dependency calculation take longer and small (often implementation, not interface) changes to force more files to be recompiled.

    – user79758
    Jan 5 '11 at 22:42






  • 14





    @Joe: Yes, and there's still no noticeable cost. C++ uses templates, that's just something we all have to understand, accept, and get over.

    – GManNickG
    Jan 5 '11 at 22:54






  • 36





    Wait, what's this "copysign is slow" business...? Using current compilers (g++ 4.6+, clang++ 3.0), std::copysign seems to result in excellent code for me: 4 instructions (inlined), no branching, entirely using the FPU. The recipe given in this answer, by contrast, generates much worse code (many more instructions, including a multiply, moving back and forth between integer unit and FPU)...

    – snogglethorpe
    Jan 23 '12 at 6:35








  • 13





    @snogglethorpe: If you're calling copysign on an int it promotes to float/double, and must narrow again on return. Your compiler may optimize that promotion out but I can't find anything suggesting that's guaranteed by the standard. Also to implement signum via copysign you need to manually handle the 0 case - please make sure you include that in any performance comparison.

    – user79758
    Jan 23 '12 at 9:31








  • 42





    The first version is not branchless. Why do people think that a comparison used in an expression will not generate a branch? It will on most architectures. Only processors that have a cmove (or predication) will generate branchless code, but they'll do it also for ternaries or if/else if it is a win.

    – Patrick Schlüter
    Mar 12 '12 at 15:41



















251














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)





share|improve this answer





















  • 6





    Also one that works without branches. Nice.

    – Joey
    Dec 14 '09 at 22:31






  • 6





    Mark Ransom, your expressions give incorrect results for x==0.

    – avakar
    Dec 14 '09 at 22:45






  • 10





    @Svante: not exactly. A value of 0 is "false"; any other value is "true"; however, the relational and equality operators always return 0 or 1 (see Standard 6.5.8 and 6.5.9). -- the value of the expression a * (x == 42) is either 0 or a.

    – pmg
    Dec 14 '09 at 23:21






  • 21





    High-Performance Mark, I'm amazed that you missed the C++ tag. This answer is very much valid and doesn't deserve a down-vote. Moreover, I wouldn't use copysign for integral x even if I had it available.

    – avakar
    Dec 15 '09 at 8:39






  • 4





    Has anyone actually checked what code GCC/G++/any other compiler emits on a real platform? My guess is that the "branchless" version uses two branches instead of one. Bitshifting is probably a lot faster - and more portable in terms of performance.

    – Jørgen Fogh
    Sep 2 '11 at 11:29



















173














There is a C99 math library function called copysign(), which takes the sign from one argument and the absolute value from the other:



result = copysign(1.0, value) // double
result = copysignf(1.0, value) // float
result = copysignl(1.0, value) // long double


will give you a result of +/- 1.0, depending on the sign of value. Note that floating point zeroes are signed: (+0) will yield +1, and (-0) will yield -1.






share|improve this answer





















  • 51





    Upvoted this one, downvoted most popular answer. Left reeling in amazement that SO community seems to prefer a hack to use of a standard library function. May the gods of programming condemn you all to trying to decipher hacks used by clever programmers unfamiliar with language standards. Yeah, I know this is going to cost me a ton of rep on SO, but I'd rather side with comingstorm than the rest of you ...

    – High Performance Mark
    Dec 15 '09 at 7:42






  • 26





    This is close, but it gives the wrong answer for zero (according to the Wikipedia article in the question at least). Nice suggestion though. +1 anyway.

    – Mark Byers
    Dec 15 '09 at 8:25






  • 4





    If you want an integer, or if you want the exact signum result for zeros, I like Mark Byers' answer, which is fiendishly elegant! If you don't care about the above, copysign() might have a performance advanage, depending on the application -- if I were optimizing a critical loop, I would try both.

    – comingstorm
    Dec 16 '09 at 10:08






  • 10





    1) C99 is not fully supported everywhere (consider VC++); 2) this is also a C++ question. This is a good answer, but the upvoted one also works, and is more widely applicable.

    – Pavel Minaev
    Dec 31 '09 at 9:17






  • 5





    Savior! Needed a way to determine between -0.0 and 0.0

    – Ólafur Waage
    May 14 '11 at 13:32



















67














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






share|improve this answer



















  • 2





    Actually there is one : en.cppreference.com/w/cpp/numeric/math/copysign. Use : std::copysign(1, x); Note that the return type is not integral.

    – SR_
    Nov 14 '17 at 12:15



















62














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






share|improve this answer



















  • 4





    This should be the most top-voted answer, as it gives the closest possible solution to what's asked in the question.

    – BartoszKP
    Mar 20 '15 at 14:20











  • I have been wondering for the past few minutes why the standard library doesn't have sign function. It is just so common -- definitely more commonly used than gamma function which could be found in cmath header.

    – Taozi
    Feb 22 '16 at 22:33






  • 3





    The explanation I often get for similar questions is "it's easy enough to implement yourself" Which IMO is not a good reason. It completely belies the problems of where standardization, unobvious edge cases, and where to put such a widely used tool.

    – Catskul
    Feb 22 '16 at 22:35





















28














Faster than the above solutions, including the highest rated one:



(x < 0) ? -1 : (x > 0)





share|improve this answer


























  • What type is x? Or are you using a #define?

    – Chance
    Feb 20 '12 at 18:11






  • 3





    Your type is not faster. It will cause a cache miss quite often.

    – Jeffrey Drake
    Dec 30 '12 at 3:19






  • 16





    Cache miss? I'm not sure how. Perhaps you meant branch misprediction?

    – Catskul
    Jun 1 '13 at 5:10






  • 1





    It seems to me this will result in a warning of confusing integer and boolean types!

    – sergiol
    Sep 2 '15 at 11:55











  • how this will be fast with the branch?

    – Nick
    Jul 15 '17 at 19:55



















17















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





share|improve this answer



















  • 1





    Ah, exactly what I'm after. This just changed in Pharo Smalltalk github.com/pharo-project/pharo/pull/1835 and I wondered if there was some sort of standard (IEC 60559 or ISO 10967) dictating behavior for negative zero and nan behaviour... I like the javascript sign developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – aka.nice
    Sep 30 '18 at 19:27





















16














There's a way to do it without branching, but it's not very pretty.



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


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



Lots of other interesting, overly-clever stuff on that page, too...






share|improve this answer



















  • 1





    If I read the link correctly that only returns -1 or 0. If you want -1, 0, or +1 then it's sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); or sign = (v > 0) - (v < 0);.

    – Z boson
    Apr 21 '15 at 7:58








  • 1





    Not exactly what we call portable code...

    – flederwiesel
    Dec 1 '16 at 18:18



















11














If all you want is to test the sign, use signbit (returns true if its argument has a negative sign).
Not sure why you would particularly want -1 or +1 returned; copysign is more convenient
for that, but it sounds like it will return +1 for negative zero on some platforms with
only partial support for negative zero, where signbit presumably would return true.






share|improve this answer





















  • 5





    There's many mathematical applications in which the sign(x) is necessary. Otherwise I'd just do if (x < 0).

    – Chance
    Mar 9 '12 at 16:42



















5














In general, there is no standard signum function in C/C++, and the lack of such a fundamental function tells you a lot about these languages.



Apart from that, I believe both majority viewpoints about the right approach to define such a function are in a way correct, and the "controversy" about it is actually a non-argument once you take into account two important caveats:




  • A signum function should always return the type of its operand, similarly to an abs() function, because signum is usually used for multiplication with an absolute value after the latter has been processed somehow. Therefore, the major use case of signum is not comparisons but arithmetic, and the latter shouldn't involve any expensive integer-to/from-floating-point conversions.


  • Floating point types do not feature a single exact zero value: +0.0 can be interpreted as "infinitesimally above zero", and -0.0 as "infinitesimally below zero". That's the reason why comparisons involving zero must internally check against both values, and an expression like x == 0.0 can be dangerous.



Regarding C, I think the best way forward with integral types is indeed to use the (x > 0) - (x < 0) expression, as it should be translated in a branch-free fashion, and requires only three basic operations. Best define inline functions that enforce a return type matching the argument type, and add a C11 define _Generic to map these functions to a common name.



With floating point values, I think inline functions based on C11 copysignf(1.0f, x), copysign(1.0, x), and copysignl(1.0l, x) are the way to go, simply because they're also highly likely to be branch-free, and additionally do not require casting the result from integer back into a floating point value. You should probably comment prominently that your floating point implementations of signum will not return zero because of the peculiarities of floating point zero values, processing time considerations, and also because it is often very useful in floating point arithmetic to receive the correct -1/+1 sign, even for zero values.






share|improve this answer

































    4














    My copy of C in a Nutshell reveals the existence of a standard function called copysign which might be useful. It looks as if copysign(1.0, -2.0) would return -1.0 and copysign(1.0, 2.0) would return +1.0.



    Pretty close huh?






    share|improve this answer


























    • Not standard, but may be widely available. Microsoft's starts with an underscore, which is the convention they use for non-standard extensions. Not the best choice when you're working with integers, though.

      – Mark Ransom
      Dec 14 '09 at 23:33






    • 5





      copysign is both in the ISO C (C99) and POSIX standards. See opengroup.org/onlinepubs/000095399/functions/copysign.html

      – lhf
      Dec 15 '09 at 1:19






    • 3





      What lhf said. Visual Studio is not a reference for the C standard.

      – Stephen Canon
      Dec 15 '09 at 1:42



















    3














    No, it doesn't exist in c++, like in matlab. I use a macro in my programs for this.



    #define sign(a) ( ( (a) < 0 )  ?  -1   : ( (a) > 0 ) )





    share|improve this answer



















    • 4





      One should prefer templates over macros in C++.

      – Ruslan
      Jan 27 '16 at 11:06











    • In C, there is no template ...... helloacm.com/how-to-implement-the-sgn-function-in-c

      – justyy
      Oct 20 '16 at 10:55











    • I thought this was a good answer then I looked at my own code and found this: #define sign(x) (((x) > 0) - ((x) < 0)) which is good too.

      – Michel Rouzic
      Feb 25 '18 at 12:12






    • 1





      an inline function is better than a macro in C, and in C++ template is better

      – phuclv
      Apr 10 '18 at 16:05



















    3














    The accepted Answer with the overload below does indeed not trigger -Wtype-limits however it triggers -Wunused-parameter on the is_signed argument.



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


    For C++11 an alternative could be.



    template <typename T>
    typename std::enable_if<std::is_unsigned<T>::value, int>::type
    inline constexpr signum(T x) {
    return T(0) < x;
    }

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


    For me it does not trigger any warnings on GCC 5.3.1






    share|improve this answer


























    • To avoid the -Wunused-parameter warning just use unnamed parameters.

      – Jonathan Wakely
      Jan 24 at 12:47











    • That is actually very true. I missed that. However, I like the C++11 alternative more either way.

      – SamVanDonut
      yesterday



















    1














    Bit off-topic, but I use this:



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


    and I found first function - the one with two arguments, to be much more useful from "standard" sgn(), because it is most often used in code like this:



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


    vs.



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


    there is no cast for unsigned types and no additional minus.



    in fact i have this piece of code using 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);
    }





    share|improve this answer































      1














      You can use boost::math::sign() method from boost/math/special_functions/sign.hpp if boost is available.






      share|improve this answer
























      • Note that this was suggested before: stackoverflow.com/a/16869019/1187415.

        – Martin R
        Aug 29 '18 at 8:41



















      0














      int sign(float n)
      {
      union { float f; std::uint32_t i; } u { n };
      return 1 - ((u.i >> 31) << 1);
      }


      This function assumes:





      • binary32 representation of floating point numbers

      • a compiler that make an exception about the strict aliasing rule when using a named union






      share|improve this answer





















      • 3





        There are still some bad assumptions here. For example I don't believe the endianness of the float is guaranteed to be the endianness of the integer. Your check also fails on any architectures using ILP64. Really, you're just reimplementing copysign; if you're using static_assert you've got C++11, and might as well really use copysign.

        – user79758
        Mar 15 '12 at 18:24





















      0














      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...)






      share|improve this answer































        0














        Here's a branching-friendly implementation:



        inline int signum(const double x) {
        if(x == 0) return 0;
        return (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
        }


        Unless your data has zeros as half of the numbers, here the branch predictor will choose one of the branches as the most common. Both branches only involve simple operations.



        Alternatively, on some compilers and CPU architectures a completely branchless version may be faster:



        inline int signum(const double x) {
        return (x != 0) *
        (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
        }


        This works for IEEE 754 double-precision binary floating-point format: binary64 .






        share|improve this answer

































          -1














          Why use ternary operators and if-else when you can simply do this



          #define sgn(x) x==0 ? 0 : x/abs(x)





          share|improve this answer



















          • 1





            Your definition uses a ternary operator as well.

            – Martin R
            Jun 30 '18 at 14:26











          • Yes Definitely, but it just uses one ternary operator to separate zero and non-zero numbers. Others' versions include nested ternary ops to separate positive, negative and zero.

            – Jagreet
            Jun 30 '18 at 16:15





















          -2














          double signof(double a) { return (a == 0) ? 0 : (a<0 ? -1 : 1); }





          share|improve this answer

































            -2














            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.






            share|improve this answer































              -2














              What about:



              int sgn = x/fabs(x);


              it should work out pretty good.






              share|improve this answer





















              • 5





                What happens when x == 0.0 ?

                – Paul R
                Jun 20 '17 at 7:30






              • 1





                and the performance would be pretty bad, too

                – phuclv
                Jun 30 '18 at 3:26



















              -5














              use:



              `#define sgn(x) (x<0)` 


              for example:



              `if(sng(n)) { etc ....}`


              Or you may want to use some elaborated code, but casting first:



              inline bool sgn_long(long x)
              {
              return ((x<0)? true: false);
              }






              share|improve this answer



















              • 1





                The question was about a function that returns -1/0/+1 for negative/zero/positive numbers.

                – Martin R
                Nov 17 '17 at 10:03











              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1903954%2fis-there-a-standard-sign-function-signum-sgn-in-c-c%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              23 Answers
              23






              active

              oldest

              votes








              23 Answers
              23






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              446














              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.)








              share|improve this answer





















              • 16





                @GMan: GCC only just now (4.5) stopped having cost quadratic to the number of instantiations for template functions, and they are still drastically more expensive to parse and instantiate than manually written functions or the standard C preprocessor. The linker also has to do more work to remove duplicate instantiations. Templates also encourage #includes-in-#includes, which makes dependency calculation take longer and small (often implementation, not interface) changes to force more files to be recompiled.

                – user79758
                Jan 5 '11 at 22:42






              • 14





                @Joe: Yes, and there's still no noticeable cost. C++ uses templates, that's just something we all have to understand, accept, and get over.

                – GManNickG
                Jan 5 '11 at 22:54






              • 36





                Wait, what's this "copysign is slow" business...? Using current compilers (g++ 4.6+, clang++ 3.0), std::copysign seems to result in excellent code for me: 4 instructions (inlined), no branching, entirely using the FPU. The recipe given in this answer, by contrast, generates much worse code (many more instructions, including a multiply, moving back and forth between integer unit and FPU)...

                – snogglethorpe
                Jan 23 '12 at 6:35








              • 13





                @snogglethorpe: If you're calling copysign on an int it promotes to float/double, and must narrow again on return. Your compiler may optimize that promotion out but I can't find anything suggesting that's guaranteed by the standard. Also to implement signum via copysign you need to manually handle the 0 case - please make sure you include that in any performance comparison.

                – user79758
                Jan 23 '12 at 9:31








              • 42





                The first version is not branchless. Why do people think that a comparison used in an expression will not generate a branch? It will on most architectures. Only processors that have a cmove (or predication) will generate branchless code, but they'll do it also for ternaries or if/else if it is a win.

                – Patrick Schlüter
                Mar 12 '12 at 15:41
















              446














              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.)








              share|improve this answer





















              • 16





                @GMan: GCC only just now (4.5) stopped having cost quadratic to the number of instantiations for template functions, and they are still drastically more expensive to parse and instantiate than manually written functions or the standard C preprocessor. The linker also has to do more work to remove duplicate instantiations. Templates also encourage #includes-in-#includes, which makes dependency calculation take longer and small (often implementation, not interface) changes to force more files to be recompiled.

                – user79758
                Jan 5 '11 at 22:42






              • 14





                @Joe: Yes, and there's still no noticeable cost. C++ uses templates, that's just something we all have to understand, accept, and get over.

                – GManNickG
                Jan 5 '11 at 22:54






              • 36





                Wait, what's this "copysign is slow" business...? Using current compilers (g++ 4.6+, clang++ 3.0), std::copysign seems to result in excellent code for me: 4 instructions (inlined), no branching, entirely using the FPU. The recipe given in this answer, by contrast, generates much worse code (many more instructions, including a multiply, moving back and forth between integer unit and FPU)...

                – snogglethorpe
                Jan 23 '12 at 6:35








              • 13





                @snogglethorpe: If you're calling copysign on an int it promotes to float/double, and must narrow again on return. Your compiler may optimize that promotion out but I can't find anything suggesting that's guaranteed by the standard. Also to implement signum via copysign you need to manually handle the 0 case - please make sure you include that in any performance comparison.

                – user79758
                Jan 23 '12 at 9:31








              • 42





                The first version is not branchless. Why do people think that a comparison used in an expression will not generate a branch? It will on most architectures. Only processors that have a cmove (or predication) will generate branchless code, but they'll do it also for ternaries or if/else if it is a win.

                – Patrick Schlüter
                Mar 12 '12 at 15:41














              446












              446








              446







              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.)








              share|improve this answer















              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.)









              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Mar 28 '12 at 13:58

























              answered Jan 5 '11 at 22:19







              user79758















              • 16





                @GMan: GCC only just now (4.5) stopped having cost quadratic to the number of instantiations for template functions, and they are still drastically more expensive to parse and instantiate than manually written functions or the standard C preprocessor. The linker also has to do more work to remove duplicate instantiations. Templates also encourage #includes-in-#includes, which makes dependency calculation take longer and small (often implementation, not interface) changes to force more files to be recompiled.

                – user79758
                Jan 5 '11 at 22:42






              • 14





                @Joe: Yes, and there's still no noticeable cost. C++ uses templates, that's just something we all have to understand, accept, and get over.

                – GManNickG
                Jan 5 '11 at 22:54






              • 36





                Wait, what's this "copysign is slow" business...? Using current compilers (g++ 4.6+, clang++ 3.0), std::copysign seems to result in excellent code for me: 4 instructions (inlined), no branching, entirely using the FPU. The recipe given in this answer, by contrast, generates much worse code (many more instructions, including a multiply, moving back and forth between integer unit and FPU)...

                – snogglethorpe
                Jan 23 '12 at 6:35








              • 13





                @snogglethorpe: If you're calling copysign on an int it promotes to float/double, and must narrow again on return. Your compiler may optimize that promotion out but I can't find anything suggesting that's guaranteed by the standard. Also to implement signum via copysign you need to manually handle the 0 case - please make sure you include that in any performance comparison.

                – user79758
                Jan 23 '12 at 9:31








              • 42





                The first version is not branchless. Why do people think that a comparison used in an expression will not generate a branch? It will on most architectures. Only processors that have a cmove (or predication) will generate branchless code, but they'll do it also for ternaries or if/else if it is a win.

                – Patrick Schlüter
                Mar 12 '12 at 15:41














              • 16





                @GMan: GCC only just now (4.5) stopped having cost quadratic to the number of instantiations for template functions, and they are still drastically more expensive to parse and instantiate than manually written functions or the standard C preprocessor. The linker also has to do more work to remove duplicate instantiations. Templates also encourage #includes-in-#includes, which makes dependency calculation take longer and small (often implementation, not interface) changes to force more files to be recompiled.

                – user79758
                Jan 5 '11 at 22:42






              • 14





                @Joe: Yes, and there's still no noticeable cost. C++ uses templates, that's just something we all have to understand, accept, and get over.

                – GManNickG
                Jan 5 '11 at 22:54






              • 36





                Wait, what's this "copysign is slow" business...? Using current compilers (g++ 4.6+, clang++ 3.0), std::copysign seems to result in excellent code for me: 4 instructions (inlined), no branching, entirely using the FPU. The recipe given in this answer, by contrast, generates much worse code (many more instructions, including a multiply, moving back and forth between integer unit and FPU)...

                – snogglethorpe
                Jan 23 '12 at 6:35








              • 13





                @snogglethorpe: If you're calling copysign on an int it promotes to float/double, and must narrow again on return. Your compiler may optimize that promotion out but I can't find anything suggesting that's guaranteed by the standard. Also to implement signum via copysign you need to manually handle the 0 case - please make sure you include that in any performance comparison.

                – user79758
                Jan 23 '12 at 9:31








              • 42





                The first version is not branchless. Why do people think that a comparison used in an expression will not generate a branch? It will on most architectures. Only processors that have a cmove (or predication) will generate branchless code, but they'll do it also for ternaries or if/else if it is a win.

                – Patrick Schlüter
                Mar 12 '12 at 15:41








              16




              16





              @GMan: GCC only just now (4.5) stopped having cost quadratic to the number of instantiations for template functions, and they are still drastically more expensive to parse and instantiate than manually written functions or the standard C preprocessor. The linker also has to do more work to remove duplicate instantiations. Templates also encourage #includes-in-#includes, which makes dependency calculation take longer and small (often implementation, not interface) changes to force more files to be recompiled.

              – user79758
              Jan 5 '11 at 22:42





              @GMan: GCC only just now (4.5) stopped having cost quadratic to the number of instantiations for template functions, and they are still drastically more expensive to parse and instantiate than manually written functions or the standard C preprocessor. The linker also has to do more work to remove duplicate instantiations. Templates also encourage #includes-in-#includes, which makes dependency calculation take longer and small (often implementation, not interface) changes to force more files to be recompiled.

              – user79758
              Jan 5 '11 at 22:42




              14




              14





              @Joe: Yes, and there's still no noticeable cost. C++ uses templates, that's just something we all have to understand, accept, and get over.

              – GManNickG
              Jan 5 '11 at 22:54





              @Joe: Yes, and there's still no noticeable cost. C++ uses templates, that's just something we all have to understand, accept, and get over.

              – GManNickG
              Jan 5 '11 at 22:54




              36




              36





              Wait, what's this "copysign is slow" business...? Using current compilers (g++ 4.6+, clang++ 3.0), std::copysign seems to result in excellent code for me: 4 instructions (inlined), no branching, entirely using the FPU. The recipe given in this answer, by contrast, generates much worse code (many more instructions, including a multiply, moving back and forth between integer unit and FPU)...

              – snogglethorpe
              Jan 23 '12 at 6:35







              Wait, what's this "copysign is slow" business...? Using current compilers (g++ 4.6+, clang++ 3.0), std::copysign seems to result in excellent code for me: 4 instructions (inlined), no branching, entirely using the FPU. The recipe given in this answer, by contrast, generates much worse code (many more instructions, including a multiply, moving back and forth between integer unit and FPU)...

              – snogglethorpe
              Jan 23 '12 at 6:35






              13




              13





              @snogglethorpe: If you're calling copysign on an int it promotes to float/double, and must narrow again on return. Your compiler may optimize that promotion out but I can't find anything suggesting that's guaranteed by the standard. Also to implement signum via copysign you need to manually handle the 0 case - please make sure you include that in any performance comparison.

              – user79758
              Jan 23 '12 at 9:31







              @snogglethorpe: If you're calling copysign on an int it promotes to float/double, and must narrow again on return. Your compiler may optimize that promotion out but I can't find anything suggesting that's guaranteed by the standard. Also to implement signum via copysign you need to manually handle the 0 case - please make sure you include that in any performance comparison.

              – user79758
              Jan 23 '12 at 9:31






              42




              42





              The first version is not branchless. Why do people think that a comparison used in an expression will not generate a branch? It will on most architectures. Only processors that have a cmove (or predication) will generate branchless code, but they'll do it also for ternaries or if/else if it is a win.

              – Patrick Schlüter
              Mar 12 '12 at 15:41





              The first version is not branchless. Why do people think that a comparison used in an expression will not generate a branch? It will on most architectures. Only processors that have a cmove (or predication) will generate branchless code, but they'll do it also for ternaries or if/else if it is a win.

              – Patrick Schlüter
              Mar 12 '12 at 15:41













              251














              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)





              share|improve this answer





















              • 6





                Also one that works without branches. Nice.

                – Joey
                Dec 14 '09 at 22:31






              • 6





                Mark Ransom, your expressions give incorrect results for x==0.

                – avakar
                Dec 14 '09 at 22:45






              • 10





                @Svante: not exactly. A value of 0 is "false"; any other value is "true"; however, the relational and equality operators always return 0 or 1 (see Standard 6.5.8 and 6.5.9). -- the value of the expression a * (x == 42) is either 0 or a.

                – pmg
                Dec 14 '09 at 23:21






              • 21





                High-Performance Mark, I'm amazed that you missed the C++ tag. This answer is very much valid and doesn't deserve a down-vote. Moreover, I wouldn't use copysign for integral x even if I had it available.

                – avakar
                Dec 15 '09 at 8:39






              • 4





                Has anyone actually checked what code GCC/G++/any other compiler emits on a real platform? My guess is that the "branchless" version uses two branches instead of one. Bitshifting is probably a lot faster - and more portable in terms of performance.

                – Jørgen Fogh
                Sep 2 '11 at 11:29
















              251














              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)





              share|improve this answer





















              • 6





                Also one that works without branches. Nice.

                – Joey
                Dec 14 '09 at 22:31






              • 6





                Mark Ransom, your expressions give incorrect results for x==0.

                – avakar
                Dec 14 '09 at 22:45






              • 10





                @Svante: not exactly. A value of 0 is "false"; any other value is "true"; however, the relational and equality operators always return 0 or 1 (see Standard 6.5.8 and 6.5.9). -- the value of the expression a * (x == 42) is either 0 or a.

                – pmg
                Dec 14 '09 at 23:21






              • 21





                High-Performance Mark, I'm amazed that you missed the C++ tag. This answer is very much valid and doesn't deserve a down-vote. Moreover, I wouldn't use copysign for integral x even if I had it available.

                – avakar
                Dec 15 '09 at 8:39






              • 4





                Has anyone actually checked what code GCC/G++/any other compiler emits on a real platform? My guess is that the "branchless" version uses two branches instead of one. Bitshifting is probably a lot faster - and more portable in terms of performance.

                – Jørgen Fogh
                Sep 2 '11 at 11:29














              251












              251








              251







              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)





              share|improve this answer















              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)






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 15 '09 at 8:19

























              answered Dec 14 '09 at 22:30









              Mark ByersMark Byers

              588k12513491338




              588k12513491338








              • 6





                Also one that works without branches. Nice.

                – Joey
                Dec 14 '09 at 22:31






              • 6





                Mark Ransom, your expressions give incorrect results for x==0.

                – avakar
                Dec 14 '09 at 22:45






              • 10





                @Svante: not exactly. A value of 0 is "false"; any other value is "true"; however, the relational and equality operators always return 0 or 1 (see Standard 6.5.8 and 6.5.9). -- the value of the expression a * (x == 42) is either 0 or a.

                – pmg
                Dec 14 '09 at 23:21






              • 21





                High-Performance Mark, I'm amazed that you missed the C++ tag. This answer is very much valid and doesn't deserve a down-vote. Moreover, I wouldn't use copysign for integral x even if I had it available.

                – avakar
                Dec 15 '09 at 8:39






              • 4





                Has anyone actually checked what code GCC/G++/any other compiler emits on a real platform? My guess is that the "branchless" version uses two branches instead of one. Bitshifting is probably a lot faster - and more portable in terms of performance.

                – Jørgen Fogh
                Sep 2 '11 at 11:29














              • 6





                Also one that works without branches. Nice.

                – Joey
                Dec 14 '09 at 22:31






              • 6





                Mark Ransom, your expressions give incorrect results for x==0.

                – avakar
                Dec 14 '09 at 22:45






              • 10





                @Svante: not exactly. A value of 0 is "false"; any other value is "true"; however, the relational and equality operators always return 0 or 1 (see Standard 6.5.8 and 6.5.9). -- the value of the expression a * (x == 42) is either 0 or a.

                – pmg
                Dec 14 '09 at 23:21






              • 21





                High-Performance Mark, I'm amazed that you missed the C++ tag. This answer is very much valid and doesn't deserve a down-vote. Moreover, I wouldn't use copysign for integral x even if I had it available.

                – avakar
                Dec 15 '09 at 8:39






              • 4





                Has anyone actually checked what code GCC/G++/any other compiler emits on a real platform? My guess is that the "branchless" version uses two branches instead of one. Bitshifting is probably a lot faster - and more portable in terms of performance.

                – Jørgen Fogh
                Sep 2 '11 at 11:29








              6




              6





              Also one that works without branches. Nice.

              – Joey
              Dec 14 '09 at 22:31





              Also one that works without branches. Nice.

              – Joey
              Dec 14 '09 at 22:31




              6




              6





              Mark Ransom, your expressions give incorrect results for x==0.

              – avakar
              Dec 14 '09 at 22:45





              Mark Ransom, your expressions give incorrect results for x==0.

              – avakar
              Dec 14 '09 at 22:45




              10




              10





              @Svante: not exactly. A value of 0 is "false"; any other value is "true"; however, the relational and equality operators always return 0 or 1 (see Standard 6.5.8 and 6.5.9). -- the value of the expression a * (x == 42) is either 0 or a.

              – pmg
              Dec 14 '09 at 23:21





              @Svante: not exactly. A value of 0 is "false"; any other value is "true"; however, the relational and equality operators always return 0 or 1 (see Standard 6.5.8 and 6.5.9). -- the value of the expression a * (x == 42) is either 0 or a.

              – pmg
              Dec 14 '09 at 23:21




              21




              21





              High-Performance Mark, I'm amazed that you missed the C++ tag. This answer is very much valid and doesn't deserve a down-vote. Moreover, I wouldn't use copysign for integral x even if I had it available.

              – avakar
              Dec 15 '09 at 8:39





              High-Performance Mark, I'm amazed that you missed the C++ tag. This answer is very much valid and doesn't deserve a down-vote. Moreover, I wouldn't use copysign for integral x even if I had it available.

              – avakar
              Dec 15 '09 at 8:39




              4




              4





              Has anyone actually checked what code GCC/G++/any other compiler emits on a real platform? My guess is that the "branchless" version uses two branches instead of one. Bitshifting is probably a lot faster - and more portable in terms of performance.

              – Jørgen Fogh
              Sep 2 '11 at 11:29





              Has anyone actually checked what code GCC/G++/any other compiler emits on a real platform? My guess is that the "branchless" version uses two branches instead of one. Bitshifting is probably a lot faster - and more portable in terms of performance.

              – Jørgen Fogh
              Sep 2 '11 at 11:29











              173














              There is a C99 math library function called copysign(), which takes the sign from one argument and the absolute value from the other:



              result = copysign(1.0, value) // double
              result = copysignf(1.0, value) // float
              result = copysignl(1.0, value) // long double


              will give you a result of +/- 1.0, depending on the sign of value. Note that floating point zeroes are signed: (+0) will yield +1, and (-0) will yield -1.






              share|improve this answer





















              • 51





                Upvoted this one, downvoted most popular answer. Left reeling in amazement that SO community seems to prefer a hack to use of a standard library function. May the gods of programming condemn you all to trying to decipher hacks used by clever programmers unfamiliar with language standards. Yeah, I know this is going to cost me a ton of rep on SO, but I'd rather side with comingstorm than the rest of you ...

                – High Performance Mark
                Dec 15 '09 at 7:42






              • 26





                This is close, but it gives the wrong answer for zero (according to the Wikipedia article in the question at least). Nice suggestion though. +1 anyway.

                – Mark Byers
                Dec 15 '09 at 8:25






              • 4





                If you want an integer, or if you want the exact signum result for zeros, I like Mark Byers' answer, which is fiendishly elegant! If you don't care about the above, copysign() might have a performance advanage, depending on the application -- if I were optimizing a critical loop, I would try both.

                – comingstorm
                Dec 16 '09 at 10:08






              • 10





                1) C99 is not fully supported everywhere (consider VC++); 2) this is also a C++ question. This is a good answer, but the upvoted one also works, and is more widely applicable.

                – Pavel Minaev
                Dec 31 '09 at 9:17






              • 5





                Savior! Needed a way to determine between -0.0 and 0.0

                – Ólafur Waage
                May 14 '11 at 13:32
















              173














              There is a C99 math library function called copysign(), which takes the sign from one argument and the absolute value from the other:



              result = copysign(1.0, value) // double
              result = copysignf(1.0, value) // float
              result = copysignl(1.0, value) // long double


              will give you a result of +/- 1.0, depending on the sign of value. Note that floating point zeroes are signed: (+0) will yield +1, and (-0) will yield -1.






              share|improve this answer





















              • 51





                Upvoted this one, downvoted most popular answer. Left reeling in amazement that SO community seems to prefer a hack to use of a standard library function. May the gods of programming condemn you all to trying to decipher hacks used by clever programmers unfamiliar with language standards. Yeah, I know this is going to cost me a ton of rep on SO, but I'd rather side with comingstorm than the rest of you ...

                – High Performance Mark
                Dec 15 '09 at 7:42






              • 26





                This is close, but it gives the wrong answer for zero (according to the Wikipedia article in the question at least). Nice suggestion though. +1 anyway.

                – Mark Byers
                Dec 15 '09 at 8:25






              • 4





                If you want an integer, or if you want the exact signum result for zeros, I like Mark Byers' answer, which is fiendishly elegant! If you don't care about the above, copysign() might have a performance advanage, depending on the application -- if I were optimizing a critical loop, I would try both.

                – comingstorm
                Dec 16 '09 at 10:08






              • 10





                1) C99 is not fully supported everywhere (consider VC++); 2) this is also a C++ question. This is a good answer, but the upvoted one also works, and is more widely applicable.

                – Pavel Minaev
                Dec 31 '09 at 9:17






              • 5





                Savior! Needed a way to determine between -0.0 and 0.0

                – Ólafur Waage
                May 14 '11 at 13:32














              173












              173








              173







              There is a C99 math library function called copysign(), which takes the sign from one argument and the absolute value from the other:



              result = copysign(1.0, value) // double
              result = copysignf(1.0, value) // float
              result = copysignl(1.0, value) // long double


              will give you a result of +/- 1.0, depending on the sign of value. Note that floating point zeroes are signed: (+0) will yield +1, and (-0) will yield -1.






              share|improve this answer















              There is a C99 math library function called copysign(), which takes the sign from one argument and the absolute value from the other:



              result = copysign(1.0, value) // double
              result = copysignf(1.0, value) // float
              result = copysignl(1.0, value) // long double


              will give you a result of +/- 1.0, depending on the sign of value. Note that floating point zeroes are signed: (+0) will yield +1, and (-0) will yield -1.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Oct 4 '11 at 1:38

























              answered Dec 15 '09 at 4:19









              comingstormcomingstorm

              19.9k12956




              19.9k12956








              • 51





                Upvoted this one, downvoted most popular answer. Left reeling in amazement that SO community seems to prefer a hack to use of a standard library function. May the gods of programming condemn you all to trying to decipher hacks used by clever programmers unfamiliar with language standards. Yeah, I know this is going to cost me a ton of rep on SO, but I'd rather side with comingstorm than the rest of you ...

                – High Performance Mark
                Dec 15 '09 at 7:42






              • 26





                This is close, but it gives the wrong answer for zero (according to the Wikipedia article in the question at least). Nice suggestion though. +1 anyway.

                – Mark Byers
                Dec 15 '09 at 8:25






              • 4





                If you want an integer, or if you want the exact signum result for zeros, I like Mark Byers' answer, which is fiendishly elegant! If you don't care about the above, copysign() might have a performance advanage, depending on the application -- if I were optimizing a critical loop, I would try both.

                – comingstorm
                Dec 16 '09 at 10:08






              • 10





                1) C99 is not fully supported everywhere (consider VC++); 2) this is also a C++ question. This is a good answer, but the upvoted one also works, and is more widely applicable.

                – Pavel Minaev
                Dec 31 '09 at 9:17






              • 5





                Savior! Needed a way to determine between -0.0 and 0.0

                – Ólafur Waage
                May 14 '11 at 13:32














              • 51





                Upvoted this one, downvoted most popular answer. Left reeling in amazement that SO community seems to prefer a hack to use of a standard library function. May the gods of programming condemn you all to trying to decipher hacks used by clever programmers unfamiliar with language standards. Yeah, I know this is going to cost me a ton of rep on SO, but I'd rather side with comingstorm than the rest of you ...

                – High Performance Mark
                Dec 15 '09 at 7:42






              • 26





                This is close, but it gives the wrong answer for zero (according to the Wikipedia article in the question at least). Nice suggestion though. +1 anyway.

                – Mark Byers
                Dec 15 '09 at 8:25






              • 4





                If you want an integer, or if you want the exact signum result for zeros, I like Mark Byers' answer, which is fiendishly elegant! If you don't care about the above, copysign() might have a performance advanage, depending on the application -- if I were optimizing a critical loop, I would try both.

                – comingstorm
                Dec 16 '09 at 10:08






              • 10





                1) C99 is not fully supported everywhere (consider VC++); 2) this is also a C++ question. This is a good answer, but the upvoted one also works, and is more widely applicable.

                – Pavel Minaev
                Dec 31 '09 at 9:17






              • 5





                Savior! Needed a way to determine between -0.0 and 0.0

                – Ólafur Waage
                May 14 '11 at 13:32








              51




              51





              Upvoted this one, downvoted most popular answer. Left reeling in amazement that SO community seems to prefer a hack to use of a standard library function. May the gods of programming condemn you all to trying to decipher hacks used by clever programmers unfamiliar with language standards. Yeah, I know this is going to cost me a ton of rep on SO, but I'd rather side with comingstorm than the rest of you ...

              – High Performance Mark
              Dec 15 '09 at 7:42





              Upvoted this one, downvoted most popular answer. Left reeling in amazement that SO community seems to prefer a hack to use of a standard library function. May the gods of programming condemn you all to trying to decipher hacks used by clever programmers unfamiliar with language standards. Yeah, I know this is going to cost me a ton of rep on SO, but I'd rather side with comingstorm than the rest of you ...

              – High Performance Mark
              Dec 15 '09 at 7:42




              26




              26





              This is close, but it gives the wrong answer for zero (according to the Wikipedia article in the question at least). Nice suggestion though. +1 anyway.

              – Mark Byers
              Dec 15 '09 at 8:25





              This is close, but it gives the wrong answer for zero (according to the Wikipedia article in the question at least). Nice suggestion though. +1 anyway.

              – Mark Byers
              Dec 15 '09 at 8:25




              4




              4





              If you want an integer, or if you want the exact signum result for zeros, I like Mark Byers' answer, which is fiendishly elegant! If you don't care about the above, copysign() might have a performance advanage, depending on the application -- if I were optimizing a critical loop, I would try both.

              – comingstorm
              Dec 16 '09 at 10:08





              If you want an integer, or if you want the exact signum result for zeros, I like Mark Byers' answer, which is fiendishly elegant! If you don't care about the above, copysign() might have a performance advanage, depending on the application -- if I were optimizing a critical loop, I would try both.

              – comingstorm
              Dec 16 '09 at 10:08




              10




              10





              1) C99 is not fully supported everywhere (consider VC++); 2) this is also a C++ question. This is a good answer, but the upvoted one also works, and is more widely applicable.

              – Pavel Minaev
              Dec 31 '09 at 9:17





              1) C99 is not fully supported everywhere (consider VC++); 2) this is also a C++ question. This is a good answer, but the upvoted one also works, and is more widely applicable.

              – Pavel Minaev
              Dec 31 '09 at 9:17




              5




              5





              Savior! Needed a way to determine between -0.0 and 0.0

              – Ólafur Waage
              May 14 '11 at 13:32





              Savior! Needed a way to determine between -0.0 and 0.0

              – Ólafur Waage
              May 14 '11 at 13:32











              67














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






              share|improve this answer



















              • 2





                Actually there is one : en.cppreference.com/w/cpp/numeric/math/copysign. Use : std::copysign(1, x); Note that the return type is not integral.

                – SR_
                Nov 14 '17 at 12:15
















              67














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






              share|improve this answer



















              • 2





                Actually there is one : en.cppreference.com/w/cpp/numeric/math/copysign. Use : std::copysign(1, x); Note that the return type is not integral.

                – SR_
                Nov 14 '17 at 12:15














              67












              67








              67







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






              share|improve this answer













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







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Apr 13 '12 at 0:24









              JohnJohn

              4,02023755




              4,02023755








              • 2





                Actually there is one : en.cppreference.com/w/cpp/numeric/math/copysign. Use : std::copysign(1, x); Note that the return type is not integral.

                – SR_
                Nov 14 '17 at 12:15














              • 2





                Actually there is one : en.cppreference.com/w/cpp/numeric/math/copysign. Use : std::copysign(1, x); Note that the return type is not integral.

                – SR_
                Nov 14 '17 at 12:15








              2




              2





              Actually there is one : en.cppreference.com/w/cpp/numeric/math/copysign. Use : std::copysign(1, x); Note that the return type is not integral.

              – SR_
              Nov 14 '17 at 12:15





              Actually there is one : en.cppreference.com/w/cpp/numeric/math/copysign. Use : std::copysign(1, x); Note that the return type is not integral.

              – SR_
              Nov 14 '17 at 12:15











              62














              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






              share|improve this answer



















              • 4





                This should be the most top-voted answer, as it gives the closest possible solution to what's asked in the question.

                – BartoszKP
                Mar 20 '15 at 14:20











              • I have been wondering for the past few minutes why the standard library doesn't have sign function. It is just so common -- definitely more commonly used than gamma function which could be found in cmath header.

                – Taozi
                Feb 22 '16 at 22:33






              • 3





                The explanation I often get for similar questions is "it's easy enough to implement yourself" Which IMO is not a good reason. It completely belies the problems of where standardization, unobvious edge cases, and where to put such a widely used tool.

                – Catskul
                Feb 22 '16 at 22:35


















              62














              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






              share|improve this answer



















              • 4





                This should be the most top-voted answer, as it gives the closest possible solution to what's asked in the question.

                – BartoszKP
                Mar 20 '15 at 14:20











              • I have been wondering for the past few minutes why the standard library doesn't have sign function. It is just so common -- definitely more commonly used than gamma function which could be found in cmath header.

                – Taozi
                Feb 22 '16 at 22:33






              • 3





                The explanation I often get for similar questions is "it's easy enough to implement yourself" Which IMO is not a good reason. It completely belies the problems of where standardization, unobvious edge cases, and where to put such a widely used tool.

                – Catskul
                Feb 22 '16 at 22:35
















              62












              62








              62







              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






              share|improve this answer













              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







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jun 1 '13 at 4:23









              CatskulCatskul

              8,00296398




              8,00296398








              • 4





                This should be the most top-voted answer, as it gives the closest possible solution to what's asked in the question.

                – BartoszKP
                Mar 20 '15 at 14:20











              • I have been wondering for the past few minutes why the standard library doesn't have sign function. It is just so common -- definitely more commonly used than gamma function which could be found in cmath header.

                – Taozi
                Feb 22 '16 at 22:33






              • 3





                The explanation I often get for similar questions is "it's easy enough to implement yourself" Which IMO is not a good reason. It completely belies the problems of where standardization, unobvious edge cases, and where to put such a widely used tool.

                – Catskul
                Feb 22 '16 at 22:35
















              • 4





                This should be the most top-voted answer, as it gives the closest possible solution to what's asked in the question.

                – BartoszKP
                Mar 20 '15 at 14:20











              • I have been wondering for the past few minutes why the standard library doesn't have sign function. It is just so common -- definitely more commonly used than gamma function which could be found in cmath header.

                – Taozi
                Feb 22 '16 at 22:33






              • 3





                The explanation I often get for similar questions is "it's easy enough to implement yourself" Which IMO is not a good reason. It completely belies the problems of where standardization, unobvious edge cases, and where to put such a widely used tool.

                – Catskul
                Feb 22 '16 at 22:35










              4




              4





              This should be the most top-voted answer, as it gives the closest possible solution to what's asked in the question.

              – BartoszKP
              Mar 20 '15 at 14:20





              This should be the most top-voted answer, as it gives the closest possible solution to what's asked in the question.

              – BartoszKP
              Mar 20 '15 at 14:20













              I have been wondering for the past few minutes why the standard library doesn't have sign function. It is just so common -- definitely more commonly used than gamma function which could be found in cmath header.

              – Taozi
              Feb 22 '16 at 22:33





              I have been wondering for the past few minutes why the standard library doesn't have sign function. It is just so common -- definitely more commonly used than gamma function which could be found in cmath header.

              – Taozi
              Feb 22 '16 at 22:33




              3




              3





              The explanation I often get for similar questions is "it's easy enough to implement yourself" Which IMO is not a good reason. It completely belies the problems of where standardization, unobvious edge cases, and where to put such a widely used tool.

              – Catskul
              Feb 22 '16 at 22:35







              The explanation I often get for similar questions is "it's easy enough to implement yourself" Which IMO is not a good reason. It completely belies the problems of where standardization, unobvious edge cases, and where to put such a widely used tool.

              – Catskul
              Feb 22 '16 at 22:35













              28














              Faster than the above solutions, including the highest rated one:



              (x < 0) ? -1 : (x > 0)





              share|improve this answer


























              • What type is x? Or are you using a #define?

                – Chance
                Feb 20 '12 at 18:11






              • 3





                Your type is not faster. It will cause a cache miss quite often.

                – Jeffrey Drake
                Dec 30 '12 at 3:19






              • 16





                Cache miss? I'm not sure how. Perhaps you meant branch misprediction?

                – Catskul
                Jun 1 '13 at 5:10






              • 1





                It seems to me this will result in a warning of confusing integer and boolean types!

                – sergiol
                Sep 2 '15 at 11:55











              • how this will be fast with the branch?

                – Nick
                Jul 15 '17 at 19:55
















              28














              Faster than the above solutions, including the highest rated one:



              (x < 0) ? -1 : (x > 0)





              share|improve this answer


























              • What type is x? Or are you using a #define?

                – Chance
                Feb 20 '12 at 18:11






              • 3





                Your type is not faster. It will cause a cache miss quite often.

                – Jeffrey Drake
                Dec 30 '12 at 3:19






              • 16





                Cache miss? I'm not sure how. Perhaps you meant branch misprediction?

                – Catskul
                Jun 1 '13 at 5:10






              • 1





                It seems to me this will result in a warning of confusing integer and boolean types!

                – sergiol
                Sep 2 '15 at 11:55











              • how this will be fast with the branch?

                – Nick
                Jul 15 '17 at 19:55














              28












              28








              28







              Faster than the above solutions, including the highest rated one:



              (x < 0) ? -1 : (x > 0)





              share|improve this answer















              Faster than the above solutions, including the highest rated one:



              (x < 0) ? -1 : (x > 0)






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Oct 11 '12 at 0:02









              Tim Cooper

              119k32239226




              119k32239226










              answered Aug 17 '11 at 20:10









              xnxxnx

              38337




              38337













              • What type is x? Or are you using a #define?

                – Chance
                Feb 20 '12 at 18:11






              • 3





                Your type is not faster. It will cause a cache miss quite often.

                – Jeffrey Drake
                Dec 30 '12 at 3:19






              • 16





                Cache miss? I'm not sure how. Perhaps you meant branch misprediction?

                – Catskul
                Jun 1 '13 at 5:10






              • 1





                It seems to me this will result in a warning of confusing integer and boolean types!

                – sergiol
                Sep 2 '15 at 11:55











              • how this will be fast with the branch?

                – Nick
                Jul 15 '17 at 19:55



















              • What type is x? Or are you using a #define?

                – Chance
                Feb 20 '12 at 18:11






              • 3





                Your type is not faster. It will cause a cache miss quite often.

                – Jeffrey Drake
                Dec 30 '12 at 3:19






              • 16





                Cache miss? I'm not sure how. Perhaps you meant branch misprediction?

                – Catskul
                Jun 1 '13 at 5:10






              • 1





                It seems to me this will result in a warning of confusing integer and boolean types!

                – sergiol
                Sep 2 '15 at 11:55











              • how this will be fast with the branch?

                – Nick
                Jul 15 '17 at 19:55

















              What type is x? Or are you using a #define?

              – Chance
              Feb 20 '12 at 18:11





              What type is x? Or are you using a #define?

              – Chance
              Feb 20 '12 at 18:11




              3




              3





              Your type is not faster. It will cause a cache miss quite often.

              – Jeffrey Drake
              Dec 30 '12 at 3:19





              Your type is not faster. It will cause a cache miss quite often.

              – Jeffrey Drake
              Dec 30 '12 at 3:19




              16




              16





              Cache miss? I'm not sure how. Perhaps you meant branch misprediction?

              – Catskul
              Jun 1 '13 at 5:10





              Cache miss? I'm not sure how. Perhaps you meant branch misprediction?

              – Catskul
              Jun 1 '13 at 5:10




              1




              1





              It seems to me this will result in a warning of confusing integer and boolean types!

              – sergiol
              Sep 2 '15 at 11:55





              It seems to me this will result in a warning of confusing integer and boolean types!

              – sergiol
              Sep 2 '15 at 11:55













              how this will be fast with the branch?

              – Nick
              Jul 15 '17 at 19:55





              how this will be fast with the branch?

              – Nick
              Jul 15 '17 at 19:55











              17















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





              share|improve this answer



















              • 1





                Ah, exactly what I'm after. This just changed in Pharo Smalltalk github.com/pharo-project/pharo/pull/1835 and I wondered if there was some sort of standard (IEC 60559 or ISO 10967) dictating behavior for negative zero and nan behaviour... I like the javascript sign developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

                – aka.nice
                Sep 30 '18 at 19:27


















              17















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





              share|improve this answer



















              • 1





                Ah, exactly what I'm after. This just changed in Pharo Smalltalk github.com/pharo-project/pharo/pull/1835 and I wondered if there was some sort of standard (IEC 60559 or ISO 10967) dictating behavior for negative zero and nan behaviour... I like the javascript sign developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

                – aka.nice
                Sep 30 '18 at 19:27
















              17












              17








              17








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





              share|improve this answer














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






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Feb 18 '16 at 20:24









              chuxchux

              82.3k872148




              82.3k872148








              • 1





                Ah, exactly what I'm after. This just changed in Pharo Smalltalk github.com/pharo-project/pharo/pull/1835 and I wondered if there was some sort of standard (IEC 60559 or ISO 10967) dictating behavior for negative zero and nan behaviour... I like the javascript sign developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

                – aka.nice
                Sep 30 '18 at 19:27
















              • 1





                Ah, exactly what I'm after. This just changed in Pharo Smalltalk github.com/pharo-project/pharo/pull/1835 and I wondered if there was some sort of standard (IEC 60559 or ISO 10967) dictating behavior for negative zero and nan behaviour... I like the javascript sign developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

                – aka.nice
                Sep 30 '18 at 19:27










              1




              1





              Ah, exactly what I'm after. This just changed in Pharo Smalltalk github.com/pharo-project/pharo/pull/1835 and I wondered if there was some sort of standard (IEC 60559 or ISO 10967) dictating behavior for negative zero and nan behaviour... I like the javascript sign developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

              – aka.nice
              Sep 30 '18 at 19:27







              Ah, exactly what I'm after. This just changed in Pharo Smalltalk github.com/pharo-project/pharo/pull/1835 and I wondered if there was some sort of standard (IEC 60559 or ISO 10967) dictating behavior for negative zero and nan behaviour... I like the javascript sign developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

              – aka.nice
              Sep 30 '18 at 19:27













              16














              There's a way to do it without branching, but it's not very pretty.



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


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



              Lots of other interesting, overly-clever stuff on that page, too...






              share|improve this answer



















              • 1





                If I read the link correctly that only returns -1 or 0. If you want -1, 0, or +1 then it's sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); or sign = (v > 0) - (v < 0);.

                – Z boson
                Apr 21 '15 at 7:58








              • 1





                Not exactly what we call portable code...

                – flederwiesel
                Dec 1 '16 at 18:18
















              16














              There's a way to do it without branching, but it's not very pretty.



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


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



              Lots of other interesting, overly-clever stuff on that page, too...






              share|improve this answer



















              • 1





                If I read the link correctly that only returns -1 or 0. If you want -1, 0, or +1 then it's sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); or sign = (v > 0) - (v < 0);.

                – Z boson
                Apr 21 '15 at 7:58








              • 1





                Not exactly what we call portable code...

                – flederwiesel
                Dec 1 '16 at 18:18














              16












              16








              16







              There's a way to do it without branching, but it's not very pretty.



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


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



              Lots of other interesting, overly-clever stuff on that page, too...






              share|improve this answer













              There's a way to do it without branching, but it's not very pretty.



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


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



              Lots of other interesting, overly-clever stuff on that page, too...







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Dec 14 '09 at 22:52









              Tim SylvesterTim Sylvester

              20.1k26584




              20.1k26584








              • 1





                If I read the link correctly that only returns -1 or 0. If you want -1, 0, or +1 then it's sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); or sign = (v > 0) - (v < 0);.

                – Z boson
                Apr 21 '15 at 7:58








              • 1





                Not exactly what we call portable code...

                – flederwiesel
                Dec 1 '16 at 18:18














              • 1





                If I read the link correctly that only returns -1 or 0. If you want -1, 0, or +1 then it's sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); or sign = (v > 0) - (v < 0);.

                – Z boson
                Apr 21 '15 at 7:58








              • 1





                Not exactly what we call portable code...

                – flederwiesel
                Dec 1 '16 at 18:18








              1




              1





              If I read the link correctly that only returns -1 or 0. If you want -1, 0, or +1 then it's sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); or sign = (v > 0) - (v < 0);.

              – Z boson
              Apr 21 '15 at 7:58







              If I read the link correctly that only returns -1 or 0. If you want -1, 0, or +1 then it's sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); or sign = (v > 0) - (v < 0);.

              – Z boson
              Apr 21 '15 at 7:58






              1




              1





              Not exactly what we call portable code...

              – flederwiesel
              Dec 1 '16 at 18:18





              Not exactly what we call portable code...

              – flederwiesel
              Dec 1 '16 at 18:18











              11














              If all you want is to test the sign, use signbit (returns true if its argument has a negative sign).
              Not sure why you would particularly want -1 or +1 returned; copysign is more convenient
              for that, but it sounds like it will return +1 for negative zero on some platforms with
              only partial support for negative zero, where signbit presumably would return true.






              share|improve this answer





















              • 5





                There's many mathematical applications in which the sign(x) is necessary. Otherwise I'd just do if (x < 0).

                – Chance
                Mar 9 '12 at 16:42
















              11














              If all you want is to test the sign, use signbit (returns true if its argument has a negative sign).
              Not sure why you would particularly want -1 or +1 returned; copysign is more convenient
              for that, but it sounds like it will return +1 for negative zero on some platforms with
              only partial support for negative zero, where signbit presumably would return true.






              share|improve this answer





















              • 5





                There's many mathematical applications in which the sign(x) is necessary. Otherwise I'd just do if (x < 0).

                – Chance
                Mar 9 '12 at 16:42














              11












              11








              11







              If all you want is to test the sign, use signbit (returns true if its argument has a negative sign).
              Not sure why you would particularly want -1 or +1 returned; copysign is more convenient
              for that, but it sounds like it will return +1 for negative zero on some platforms with
              only partial support for negative zero, where signbit presumably would return true.






              share|improve this answer















              If all you want is to test the sign, use signbit (returns true if its argument has a negative sign).
              Not sure why you would particularly want -1 or +1 returned; copysign is more convenient
              for that, but it sounds like it will return +1 for negative zero on some platforms with
              only partial support for negative zero, where signbit presumably would return true.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jan 4 '10 at 3:16

























              answered Dec 15 '09 at 5:59









              ysthysth

              78.1k494191




              78.1k494191








              • 5





                There's many mathematical applications in which the sign(x) is necessary. Otherwise I'd just do if (x < 0).

                – Chance
                Mar 9 '12 at 16:42














              • 5





                There's many mathematical applications in which the sign(x) is necessary. Otherwise I'd just do if (x < 0).

                – Chance
                Mar 9 '12 at 16:42








              5




              5





              There's many mathematical applications in which the sign(x) is necessary. Otherwise I'd just do if (x < 0).

              – Chance
              Mar 9 '12 at 16:42





              There's many mathematical applications in which the sign(x) is necessary. Otherwise I'd just do if (x < 0).

              – Chance
              Mar 9 '12 at 16:42











              5














              In general, there is no standard signum function in C/C++, and the lack of such a fundamental function tells you a lot about these languages.



              Apart from that, I believe both majority viewpoints about the right approach to define such a function are in a way correct, and the "controversy" about it is actually a non-argument once you take into account two important caveats:




              • A signum function should always return the type of its operand, similarly to an abs() function, because signum is usually used for multiplication with an absolute value after the latter has been processed somehow. Therefore, the major use case of signum is not comparisons but arithmetic, and the latter shouldn't involve any expensive integer-to/from-floating-point conversions.


              • Floating point types do not feature a single exact zero value: +0.0 can be interpreted as "infinitesimally above zero", and -0.0 as "infinitesimally below zero". That's the reason why comparisons involving zero must internally check against both values, and an expression like x == 0.0 can be dangerous.



              Regarding C, I think the best way forward with integral types is indeed to use the (x > 0) - (x < 0) expression, as it should be translated in a branch-free fashion, and requires only three basic operations. Best define inline functions that enforce a return type matching the argument type, and add a C11 define _Generic to map these functions to a common name.



              With floating point values, I think inline functions based on C11 copysignf(1.0f, x), copysign(1.0, x), and copysignl(1.0l, x) are the way to go, simply because they're also highly likely to be branch-free, and additionally do not require casting the result from integer back into a floating point value. You should probably comment prominently that your floating point implementations of signum will not return zero because of the peculiarities of floating point zero values, processing time considerations, and also because it is often very useful in floating point arithmetic to receive the correct -1/+1 sign, even for zero values.






              share|improve this answer






























                5














                In general, there is no standard signum function in C/C++, and the lack of such a fundamental function tells you a lot about these languages.



                Apart from that, I believe both majority viewpoints about the right approach to define such a function are in a way correct, and the "controversy" about it is actually a non-argument once you take into account two important caveats:




                • A signum function should always return the type of its operand, similarly to an abs() function, because signum is usually used for multiplication with an absolute value after the latter has been processed somehow. Therefore, the major use case of signum is not comparisons but arithmetic, and the latter shouldn't involve any expensive integer-to/from-floating-point conversions.


                • Floating point types do not feature a single exact zero value: +0.0 can be interpreted as "infinitesimally above zero", and -0.0 as "infinitesimally below zero". That's the reason why comparisons involving zero must internally check against both values, and an expression like x == 0.0 can be dangerous.



                Regarding C, I think the best way forward with integral types is indeed to use the (x > 0) - (x < 0) expression, as it should be translated in a branch-free fashion, and requires only three basic operations. Best define inline functions that enforce a return type matching the argument type, and add a C11 define _Generic to map these functions to a common name.



                With floating point values, I think inline functions based on C11 copysignf(1.0f, x), copysign(1.0, x), and copysignl(1.0l, x) are the way to go, simply because they're also highly likely to be branch-free, and additionally do not require casting the result from integer back into a floating point value. You should probably comment prominently that your floating point implementations of signum will not return zero because of the peculiarities of floating point zero values, processing time considerations, and also because it is often very useful in floating point arithmetic to receive the correct -1/+1 sign, even for zero values.






                share|improve this answer




























                  5












                  5








                  5







                  In general, there is no standard signum function in C/C++, and the lack of such a fundamental function tells you a lot about these languages.



                  Apart from that, I believe both majority viewpoints about the right approach to define such a function are in a way correct, and the "controversy" about it is actually a non-argument once you take into account two important caveats:




                  • A signum function should always return the type of its operand, similarly to an abs() function, because signum is usually used for multiplication with an absolute value after the latter has been processed somehow. Therefore, the major use case of signum is not comparisons but arithmetic, and the latter shouldn't involve any expensive integer-to/from-floating-point conversions.


                  • Floating point types do not feature a single exact zero value: +0.0 can be interpreted as "infinitesimally above zero", and -0.0 as "infinitesimally below zero". That's the reason why comparisons involving zero must internally check against both values, and an expression like x == 0.0 can be dangerous.



                  Regarding C, I think the best way forward with integral types is indeed to use the (x > 0) - (x < 0) expression, as it should be translated in a branch-free fashion, and requires only three basic operations. Best define inline functions that enforce a return type matching the argument type, and add a C11 define _Generic to map these functions to a common name.



                  With floating point values, I think inline functions based on C11 copysignf(1.0f, x), copysign(1.0, x), and copysignl(1.0l, x) are the way to go, simply because they're also highly likely to be branch-free, and additionally do not require casting the result from integer back into a floating point value. You should probably comment prominently that your floating point implementations of signum will not return zero because of the peculiarities of floating point zero values, processing time considerations, and also because it is often very useful in floating point arithmetic to receive the correct -1/+1 sign, even for zero values.






                  share|improve this answer















                  In general, there is no standard signum function in C/C++, and the lack of such a fundamental function tells you a lot about these languages.



                  Apart from that, I believe both majority viewpoints about the right approach to define such a function are in a way correct, and the "controversy" about it is actually a non-argument once you take into account two important caveats:




                  • A signum function should always return the type of its operand, similarly to an abs() function, because signum is usually used for multiplication with an absolute value after the latter has been processed somehow. Therefore, the major use case of signum is not comparisons but arithmetic, and the latter shouldn't involve any expensive integer-to/from-floating-point conversions.


                  • Floating point types do not feature a single exact zero value: +0.0 can be interpreted as "infinitesimally above zero", and -0.0 as "infinitesimally below zero". That's the reason why comparisons involving zero must internally check against both values, and an expression like x == 0.0 can be dangerous.



                  Regarding C, I think the best way forward with integral types is indeed to use the (x > 0) - (x < 0) expression, as it should be translated in a branch-free fashion, and requires only three basic operations. Best define inline functions that enforce a return type matching the argument type, and add a C11 define _Generic to map these functions to a common name.



                  With floating point values, I think inline functions based on C11 copysignf(1.0f, x), copysign(1.0, x), and copysignl(1.0l, x) are the way to go, simply because they're also highly likely to be branch-free, and additionally do not require casting the result from integer back into a floating point value. You should probably comment prominently that your floating point implementations of signum will not return zero because of the peculiarities of floating point zero values, processing time considerations, and also because it is often very useful in floating point arithmetic to receive the correct -1/+1 sign, even for zero values.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited May 26 '15 at 13:07









                  seh

                  13.2k3853




                  13.2k3853










                  answered May 26 '15 at 3:05









                  TabernakelTabernakel

                  6113




                  6113























                      4














                      My copy of C in a Nutshell reveals the existence of a standard function called copysign which might be useful. It looks as if copysign(1.0, -2.0) would return -1.0 and copysign(1.0, 2.0) would return +1.0.



                      Pretty close huh?






                      share|improve this answer


























                      • Not standard, but may be widely available. Microsoft's starts with an underscore, which is the convention they use for non-standard extensions. Not the best choice when you're working with integers, though.

                        – Mark Ransom
                        Dec 14 '09 at 23:33






                      • 5





                        copysign is both in the ISO C (C99) and POSIX standards. See opengroup.org/onlinepubs/000095399/functions/copysign.html

                        – lhf
                        Dec 15 '09 at 1:19






                      • 3





                        What lhf said. Visual Studio is not a reference for the C standard.

                        – Stephen Canon
                        Dec 15 '09 at 1:42
















                      4














                      My copy of C in a Nutshell reveals the existence of a standard function called copysign which might be useful. It looks as if copysign(1.0, -2.0) would return -1.0 and copysign(1.0, 2.0) would return +1.0.



                      Pretty close huh?






                      share|improve this answer


























                      • Not standard, but may be widely available. Microsoft's starts with an underscore, which is the convention they use for non-standard extensions. Not the best choice when you're working with integers, though.

                        – Mark Ransom
                        Dec 14 '09 at 23:33






                      • 5





                        copysign is both in the ISO C (C99) and POSIX standards. See opengroup.org/onlinepubs/000095399/functions/copysign.html

                        – lhf
                        Dec 15 '09 at 1:19






                      • 3





                        What lhf said. Visual Studio is not a reference for the C standard.

                        – Stephen Canon
                        Dec 15 '09 at 1:42














                      4












                      4








                      4







                      My copy of C in a Nutshell reveals the existence of a standard function called copysign which might be useful. It looks as if copysign(1.0, -2.0) would return -1.0 and copysign(1.0, 2.0) would return +1.0.



                      Pretty close huh?






                      share|improve this answer















                      My copy of C in a Nutshell reveals the existence of a standard function called copysign which might be useful. It looks as if copysign(1.0, -2.0) would return -1.0 and copysign(1.0, 2.0) would return +1.0.



                      Pretty close huh?







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Jan 22 '16 at 18:53









                      mbaitoff

                      4,70641731




                      4,70641731










                      answered Dec 14 '09 at 23:15









                      High Performance MarkHigh Performance Mark

                      68.8k783134




                      68.8k783134













                      • Not standard, but may be widely available. Microsoft's starts with an underscore, which is the convention they use for non-standard extensions. Not the best choice when you're working with integers, though.

                        – Mark Ransom
                        Dec 14 '09 at 23:33






                      • 5





                        copysign is both in the ISO C (C99) and POSIX standards. See opengroup.org/onlinepubs/000095399/functions/copysign.html

                        – lhf
                        Dec 15 '09 at 1:19






                      • 3





                        What lhf said. Visual Studio is not a reference for the C standard.

                        – Stephen Canon
                        Dec 15 '09 at 1:42



















                      • Not standard, but may be widely available. Microsoft's starts with an underscore, which is the convention they use for non-standard extensions. Not the best choice when you're working with integers, though.

                        – Mark Ransom
                        Dec 14 '09 at 23:33






                      • 5





                        copysign is both in the ISO C (C99) and POSIX standards. See opengroup.org/onlinepubs/000095399/functions/copysign.html

                        – lhf
                        Dec 15 '09 at 1:19






                      • 3





                        What lhf said. Visual Studio is not a reference for the C standard.

                        – Stephen Canon
                        Dec 15 '09 at 1:42

















                      Not standard, but may be widely available. Microsoft's starts with an underscore, which is the convention they use for non-standard extensions. Not the best choice when you're working with integers, though.

                      – Mark Ransom
                      Dec 14 '09 at 23:33





                      Not standard, but may be widely available. Microsoft's starts with an underscore, which is the convention they use for non-standard extensions. Not the best choice when you're working with integers, though.

                      – Mark Ransom
                      Dec 14 '09 at 23:33




                      5




                      5





                      copysign is both in the ISO C (C99) and POSIX standards. See opengroup.org/onlinepubs/000095399/functions/copysign.html

                      – lhf
                      Dec 15 '09 at 1:19





                      copysign is both in the ISO C (C99) and POSIX standards. See opengroup.org/onlinepubs/000095399/functions/copysign.html

                      – lhf
                      Dec 15 '09 at 1:19




                      3




                      3





                      What lhf said. Visual Studio is not a reference for the C standard.

                      – Stephen Canon
                      Dec 15 '09 at 1:42





                      What lhf said. Visual Studio is not a reference for the C standard.

                      – Stephen Canon
                      Dec 15 '09 at 1:42











                      3














                      No, it doesn't exist in c++, like in matlab. I use a macro in my programs for this.



                      #define sign(a) ( ( (a) < 0 )  ?  -1   : ( (a) > 0 ) )





                      share|improve this answer



















                      • 4





                        One should prefer templates over macros in C++.

                        – Ruslan
                        Jan 27 '16 at 11:06











                      • In C, there is no template ...... helloacm.com/how-to-implement-the-sgn-function-in-c

                        – justyy
                        Oct 20 '16 at 10:55











                      • I thought this was a good answer then I looked at my own code and found this: #define sign(x) (((x) > 0) - ((x) < 0)) which is good too.

                        – Michel Rouzic
                        Feb 25 '18 at 12:12






                      • 1





                        an inline function is better than a macro in C, and in C++ template is better

                        – phuclv
                        Apr 10 '18 at 16:05
















                      3














                      No, it doesn't exist in c++, like in matlab. I use a macro in my programs for this.



                      #define sign(a) ( ( (a) < 0 )  ?  -1   : ( (a) > 0 ) )





                      share|improve this answer



















                      • 4





                        One should prefer templates over macros in C++.

                        – Ruslan
                        Jan 27 '16 at 11:06











                      • In C, there is no template ...... helloacm.com/how-to-implement-the-sgn-function-in-c

                        – justyy
                        Oct 20 '16 at 10:55











                      • I thought this was a good answer then I looked at my own code and found this: #define sign(x) (((x) > 0) - ((x) < 0)) which is good too.

                        – Michel Rouzic
                        Feb 25 '18 at 12:12






                      • 1





                        an inline function is better than a macro in C, and in C++ template is better

                        – phuclv
                        Apr 10 '18 at 16:05














                      3












                      3








                      3







                      No, it doesn't exist in c++, like in matlab. I use a macro in my programs for this.



                      #define sign(a) ( ( (a) < 0 )  ?  -1   : ( (a) > 0 ) )





                      share|improve this answer













                      No, it doesn't exist in c++, like in matlab. I use a macro in my programs for this.



                      #define sign(a) ( ( (a) < 0 )  ?  -1   : ( (a) > 0 ) )






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Jul 10 '14 at 23:35









                      chatteringchattering

                      631




                      631








                      • 4





                        One should prefer templates over macros in C++.

                        – Ruslan
                        Jan 27 '16 at 11:06











                      • In C, there is no template ...... helloacm.com/how-to-implement-the-sgn-function-in-c

                        – justyy
                        Oct 20 '16 at 10:55











                      • I thought this was a good answer then I looked at my own code and found this: #define sign(x) (((x) > 0) - ((x) < 0)) which is good too.

                        – Michel Rouzic
                        Feb 25 '18 at 12:12






                      • 1





                        an inline function is better than a macro in C, and in C++ template is better

                        – phuclv
                        Apr 10 '18 at 16:05














                      • 4





                        One should prefer templates over macros in C++.

                        – Ruslan
                        Jan 27 '16 at 11:06











                      • In C, there is no template ...... helloacm.com/how-to-implement-the-sgn-function-in-c

                        – justyy
                        Oct 20 '16 at 10:55











                      • I thought this was a good answer then I looked at my own code and found this: #define sign(x) (((x) > 0) - ((x) < 0)) which is good too.

                        – Michel Rouzic
                        Feb 25 '18 at 12:12






                      • 1





                        an inline function is better than a macro in C, and in C++ template is better

                        – phuclv
                        Apr 10 '18 at 16:05








                      4




                      4





                      One should prefer templates over macros in C++.

                      – Ruslan
                      Jan 27 '16 at 11:06





                      One should prefer templates over macros in C++.

                      – Ruslan
                      Jan 27 '16 at 11:06













                      In C, there is no template ...... helloacm.com/how-to-implement-the-sgn-function-in-c

                      – justyy
                      Oct 20 '16 at 10:55





                      In C, there is no template ...... helloacm.com/how-to-implement-the-sgn-function-in-c

                      – justyy
                      Oct 20 '16 at 10:55













                      I thought this was a good answer then I looked at my own code and found this: #define sign(x) (((x) > 0) - ((x) < 0)) which is good too.

                      – Michel Rouzic
                      Feb 25 '18 at 12:12





                      I thought this was a good answer then I looked at my own code and found this: #define sign(x) (((x) > 0) - ((x) < 0)) which is good too.

                      – Michel Rouzic
                      Feb 25 '18 at 12:12




                      1




                      1





                      an inline function is better than a macro in C, and in C++ template is better

                      – phuclv
                      Apr 10 '18 at 16:05





                      an inline function is better than a macro in C, and in C++ template is better

                      – phuclv
                      Apr 10 '18 at 16:05











                      3














                      The accepted Answer with the overload below does indeed not trigger -Wtype-limits however it triggers -Wunused-parameter on the is_signed argument.



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


                      For C++11 an alternative could be.



                      template <typename T>
                      typename std::enable_if<std::is_unsigned<T>::value, int>::type
                      inline constexpr signum(T x) {
                      return T(0) < x;
                      }

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


                      For me it does not trigger any warnings on GCC 5.3.1






                      share|improve this answer


























                      • To avoid the -Wunused-parameter warning just use unnamed parameters.

                        – Jonathan Wakely
                        Jan 24 at 12:47











                      • That is actually very true. I missed that. However, I like the C++11 alternative more either way.

                        – SamVanDonut
                        yesterday
















                      3














                      The accepted Answer with the overload below does indeed not trigger -Wtype-limits however it triggers -Wunused-parameter on the is_signed argument.



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


                      For C++11 an alternative could be.



                      template <typename T>
                      typename std::enable_if<std::is_unsigned<T>::value, int>::type
                      inline constexpr signum(T x) {
                      return T(0) < x;
                      }

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


                      For me it does not trigger any warnings on GCC 5.3.1






                      share|improve this answer


























                      • To avoid the -Wunused-parameter warning just use unnamed parameters.

                        – Jonathan Wakely
                        Jan 24 at 12:47











                      • That is actually very true. I missed that. However, I like the C++11 alternative more either way.

                        – SamVanDonut
                        yesterday














                      3












                      3








                      3







                      The accepted Answer with the overload below does indeed not trigger -Wtype-limits however it triggers -Wunused-parameter on the is_signed argument.



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


                      For C++11 an alternative could be.



                      template <typename T>
                      typename std::enable_if<std::is_unsigned<T>::value, int>::type
                      inline constexpr signum(T x) {
                      return T(0) < x;
                      }

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


                      For me it does not trigger any warnings on GCC 5.3.1






                      share|improve this answer















                      The accepted Answer with the overload below does indeed not trigger -Wtype-limits however it triggers -Wunused-parameter on the is_signed argument.



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


                      For C++11 an alternative could be.



                      template <typename T>
                      typename std::enable_if<std::is_unsigned<T>::value, int>::type
                      inline constexpr signum(T x) {
                      return T(0) < x;
                      }

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


                      For me it does not trigger any warnings on GCC 5.3.1







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Jan 13 '17 at 17:14

























                      answered Jan 13 '17 at 15:59









                      SamVanDonutSamVanDonut

                      9219




                      9219













                      • To avoid the -Wunused-parameter warning just use unnamed parameters.

                        – Jonathan Wakely
                        Jan 24 at 12:47











                      • That is actually very true. I missed that. However, I like the C++11 alternative more either way.

                        – SamVanDonut
                        yesterday



















                      • To avoid the -Wunused-parameter warning just use unnamed parameters.

                        – Jonathan Wakely
                        Jan 24 at 12:47











                      • That is actually very true. I missed that. However, I like the C++11 alternative more either way.

                        – SamVanDonut
                        yesterday

















                      To avoid the -Wunused-parameter warning just use unnamed parameters.

                      – Jonathan Wakely
                      Jan 24 at 12:47





                      To avoid the -Wunused-parameter warning just use unnamed parameters.

                      – Jonathan Wakely
                      Jan 24 at 12:47













                      That is actually very true. I missed that. However, I like the C++11 alternative more either way.

                      – SamVanDonut
                      yesterday





                      That is actually very true. I missed that. However, I like the C++11 alternative more either way.

                      – SamVanDonut
                      yesterday











                      1














                      Bit off-topic, but I use this:



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


                      and I found first function - the one with two arguments, to be much more useful from "standard" sgn(), because it is most often used in code like this:



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


                      vs.



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


                      there is no cast for unsigned types and no additional minus.



                      in fact i have this piece of code using 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);
                      }





                      share|improve this answer




























                        1














                        Bit off-topic, but I use this:



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


                        and I found first function - the one with two arguments, to be much more useful from "standard" sgn(), because it is most often used in code like this:



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


                        vs.



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


                        there is no cast for unsigned types and no additional minus.



                        in fact i have this piece of code using 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);
                        }





                        share|improve this answer


























                          1












                          1








                          1







                          Bit off-topic, but I use this:



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


                          and I found first function - the one with two arguments, to be much more useful from "standard" sgn(), because it is most often used in code like this:



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


                          vs.



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


                          there is no cast for unsigned types and no additional minus.



                          in fact i have this piece of code using 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);
                          }





                          share|improve this answer













                          Bit off-topic, but I use this:



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


                          and I found first function - the one with two arguments, to be much more useful from "standard" sgn(), because it is most often used in code like this:



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


                          vs.



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


                          there is no cast for unsigned types and no additional minus.



                          in fact i have this piece of code using 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);
                          }






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Jul 15 '17 at 20:03









                          NickNick

                          4,43212647




                          4,43212647























                              1














                              You can use boost::math::sign() method from boost/math/special_functions/sign.hpp if boost is available.






                              share|improve this answer
























                              • Note that this was suggested before: stackoverflow.com/a/16869019/1187415.

                                – Martin R
                                Aug 29 '18 at 8:41
















                              1














                              You can use boost::math::sign() method from boost/math/special_functions/sign.hpp if boost is available.






                              share|improve this answer
























                              • Note that this was suggested before: stackoverflow.com/a/16869019/1187415.

                                – Martin R
                                Aug 29 '18 at 8:41














                              1












                              1








                              1







                              You can use boost::math::sign() method from boost/math/special_functions/sign.hpp if boost is available.






                              share|improve this answer













                              You can use boost::math::sign() method from boost/math/special_functions/sign.hpp if boost is available.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Aug 29 '18 at 7:58









                              khkarenskhkarens

                              5801514




                              5801514













                              • Note that this was suggested before: stackoverflow.com/a/16869019/1187415.

                                – Martin R
                                Aug 29 '18 at 8:41



















                              • Note that this was suggested before: stackoverflow.com/a/16869019/1187415.

                                – Martin R
                                Aug 29 '18 at 8:41

















                              Note that this was suggested before: stackoverflow.com/a/16869019/1187415.

                              – Martin R
                              Aug 29 '18 at 8:41





                              Note that this was suggested before: stackoverflow.com/a/16869019/1187415.

                              – Martin R
                              Aug 29 '18 at 8:41











                              0














                              int sign(float n)
                              {
                              union { float f; std::uint32_t i; } u { n };
                              return 1 - ((u.i >> 31) << 1);
                              }


                              This function assumes:





                              • binary32 representation of floating point numbers

                              • a compiler that make an exception about the strict aliasing rule when using a named union






                              share|improve this answer





















                              • 3





                                There are still some bad assumptions here. For example I don't believe the endianness of the float is guaranteed to be the endianness of the integer. Your check also fails on any architectures using ILP64. Really, you're just reimplementing copysign; if you're using static_assert you've got C++11, and might as well really use copysign.

                                – user79758
                                Mar 15 '12 at 18:24


















                              0














                              int sign(float n)
                              {
                              union { float f; std::uint32_t i; } u { n };
                              return 1 - ((u.i >> 31) << 1);
                              }


                              This function assumes:





                              • binary32 representation of floating point numbers

                              • a compiler that make an exception about the strict aliasing rule when using a named union






                              share|improve this answer





















                              • 3





                                There are still some bad assumptions here. For example I don't believe the endianness of the float is guaranteed to be the endianness of the integer. Your check also fails on any architectures using ILP64. Really, you're just reimplementing copysign; if you're using static_assert you've got C++11, and might as well really use copysign.

                                – user79758
                                Mar 15 '12 at 18:24
















                              0












                              0








                              0







                              int sign(float n)
                              {
                              union { float f; std::uint32_t i; } u { n };
                              return 1 - ((u.i >> 31) << 1);
                              }


                              This function assumes:





                              • binary32 representation of floating point numbers

                              • a compiler that make an exception about the strict aliasing rule when using a named union






                              share|improve this answer















                              int sign(float n)
                              {
                              union { float f; std::uint32_t i; } u { n };
                              return 1 - ((u.i >> 31) << 1);
                              }


                              This function assumes:





                              • binary32 representation of floating point numbers

                              • a compiler that make an exception about the strict aliasing rule when using a named union







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Aug 14 '12 at 19:12

























                              answered Feb 3 '12 at 1:04









                              GigiGigi

                              4,1422023




                              4,1422023








                              • 3





                                There are still some bad assumptions here. For example I don't believe the endianness of the float is guaranteed to be the endianness of the integer. Your check also fails on any architectures using ILP64. Really, you're just reimplementing copysign; if you're using static_assert you've got C++11, and might as well really use copysign.

                                – user79758
                                Mar 15 '12 at 18:24
















                              • 3





                                There are still some bad assumptions here. For example I don't believe the endianness of the float is guaranteed to be the endianness of the integer. Your check also fails on any architectures using ILP64. Really, you're just reimplementing copysign; if you're using static_assert you've got C++11, and might as well really use copysign.

                                – user79758
                                Mar 15 '12 at 18:24










                              3




                              3





                              There are still some bad assumptions here. For example I don't believe the endianness of the float is guaranteed to be the endianness of the integer. Your check also fails on any architectures using ILP64. Really, you're just reimplementing copysign; if you're using static_assert you've got C++11, and might as well really use copysign.

                              – user79758
                              Mar 15 '12 at 18:24







                              There are still some bad assumptions here. For example I don't believe the endianness of the float is guaranteed to be the endianness of the integer. Your check also fails on any architectures using ILP64. Really, you're just reimplementing copysign; if you're using static_assert you've got C++11, and might as well really use copysign.

                              – user79758
                              Mar 15 '12 at 18:24













                              0














                              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...)






                              share|improve this answer




























                                0














                                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...)






                                share|improve this answer


























                                  0












                                  0








                                  0







                                  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...)






                                  share|improve this answer













                                  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...)







                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Aug 11 '17 at 8:19









                                  mrclngmrclng

                                  1267




                                  1267























                                      0














                                      Here's a branching-friendly implementation:



                                      inline int signum(const double x) {
                                      if(x == 0) return 0;
                                      return (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
                                      }


                                      Unless your data has zeros as half of the numbers, here the branch predictor will choose one of the branches as the most common. Both branches only involve simple operations.



                                      Alternatively, on some compilers and CPU architectures a completely branchless version may be faster:



                                      inline int signum(const double x) {
                                      return (x != 0) *
                                      (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
                                      }


                                      This works for IEEE 754 double-precision binary floating-point format: binary64 .






                                      share|improve this answer






























                                        0














                                        Here's a branching-friendly implementation:



                                        inline int signum(const double x) {
                                        if(x == 0) return 0;
                                        return (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
                                        }


                                        Unless your data has zeros as half of the numbers, here the branch predictor will choose one of the branches as the most common. Both branches only involve simple operations.



                                        Alternatively, on some compilers and CPU architectures a completely branchless version may be faster:



                                        inline int signum(const double x) {
                                        return (x != 0) *
                                        (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
                                        }


                                        This works for IEEE 754 double-precision binary floating-point format: binary64 .






                                        share|improve this answer




























                                          0












                                          0








                                          0







                                          Here's a branching-friendly implementation:



                                          inline int signum(const double x) {
                                          if(x == 0) return 0;
                                          return (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
                                          }


                                          Unless your data has zeros as half of the numbers, here the branch predictor will choose one of the branches as the most common. Both branches only involve simple operations.



                                          Alternatively, on some compilers and CPU architectures a completely branchless version may be faster:



                                          inline int signum(const double x) {
                                          return (x != 0) *
                                          (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
                                          }


                                          This works for IEEE 754 double-precision binary floating-point format: binary64 .






                                          share|improve this answer















                                          Here's a branching-friendly implementation:



                                          inline int signum(const double x) {
                                          if(x == 0) return 0;
                                          return (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
                                          }


                                          Unless your data has zeros as half of the numbers, here the branch predictor will choose one of the branches as the most common. Both branches only involve simple operations.



                                          Alternatively, on some compilers and CPU architectures a completely branchless version may be faster:



                                          inline int signum(const double x) {
                                          return (x != 0) *
                                          (1 - (static_cast<int>((*reinterpret_cast<const uint64_t*>(&x)) >> 63) << 1));
                                          }


                                          This works for IEEE 754 double-precision binary floating-point format: binary64 .







                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited Nov 19 '18 at 11:41

























                                          answered Nov 19 '18 at 9:29









                                          Serge RogatchSerge Rogatch

                                          6,14623364




                                          6,14623364























                                              -1














                                              Why use ternary operators and if-else when you can simply do this



                                              #define sgn(x) x==0 ? 0 : x/abs(x)





                                              share|improve this answer



















                                              • 1





                                                Your definition uses a ternary operator as well.

                                                – Martin R
                                                Jun 30 '18 at 14:26











                                              • Yes Definitely, but it just uses one ternary operator to separate zero and non-zero numbers. Others' versions include nested ternary ops to separate positive, negative and zero.

                                                – Jagreet
                                                Jun 30 '18 at 16:15


















                                              -1














                                              Why use ternary operators and if-else when you can simply do this



                                              #define sgn(x) x==0 ? 0 : x/abs(x)





                                              share|improve this answer



















                                              • 1





                                                Your definition uses a ternary operator as well.

                                                – Martin R
                                                Jun 30 '18 at 14:26











                                              • Yes Definitely, but it just uses one ternary operator to separate zero and non-zero numbers. Others' versions include nested ternary ops to separate positive, negative and zero.

                                                – Jagreet
                                                Jun 30 '18 at 16:15
















                                              -1












                                              -1








                                              -1







                                              Why use ternary operators and if-else when you can simply do this



                                              #define sgn(x) x==0 ? 0 : x/abs(x)





                                              share|improve this answer













                                              Why use ternary operators and if-else when you can simply do this



                                              #define sgn(x) x==0 ? 0 : x/abs(x)






                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Jun 30 '18 at 1:29









                                              JagreetJagreet

                                              6319




                                              6319








                                              • 1





                                                Your definition uses a ternary operator as well.

                                                – Martin R
                                                Jun 30 '18 at 14:26











                                              • Yes Definitely, but it just uses one ternary operator to separate zero and non-zero numbers. Others' versions include nested ternary ops to separate positive, negative and zero.

                                                – Jagreet
                                                Jun 30 '18 at 16:15
















                                              • 1





                                                Your definition uses a ternary operator as well.

                                                – Martin R
                                                Jun 30 '18 at 14:26











                                              • Yes Definitely, but it just uses one ternary operator to separate zero and non-zero numbers. Others' versions include nested ternary ops to separate positive, negative and zero.

                                                – Jagreet
                                                Jun 30 '18 at 16:15










                                              1




                                              1





                                              Your definition uses a ternary operator as well.

                                              – Martin R
                                              Jun 30 '18 at 14:26





                                              Your definition uses a ternary operator as well.

                                              – Martin R
                                              Jun 30 '18 at 14:26













                                              Yes Definitely, but it just uses one ternary operator to separate zero and non-zero numbers. Others' versions include nested ternary ops to separate positive, negative and zero.

                                              – Jagreet
                                              Jun 30 '18 at 16:15







                                              Yes Definitely, but it just uses one ternary operator to separate zero and non-zero numbers. Others' versions include nested ternary ops to separate positive, negative and zero.

                                              – Jagreet
                                              Jun 30 '18 at 16:15













                                              -2














                                              double signof(double a) { return (a == 0) ? 0 : (a<0 ? -1 : 1); }





                                              share|improve this answer






























                                                -2














                                                double signof(double a) { return (a == 0) ? 0 : (a<0 ? -1 : 1); }





                                                share|improve this answer




























                                                  -2












                                                  -2








                                                  -2







                                                  double signof(double a) { return (a == 0) ? 0 : (a<0 ? -1 : 1); }





                                                  share|improve this answer















                                                  double signof(double a) { return (a == 0) ? 0 : (a<0 ? -1 : 1); }






                                                  share|improve this answer














                                                  share|improve this answer



                                                  share|improve this answer








                                                  edited Nov 4 '12 at 16:05









                                                  arrowd

                                                  22.2k44981




                                                  22.2k44981










                                                  answered Nov 4 '12 at 15:46









                                                  cyberioncyberion

                                                  283




                                                  283























                                                      -2














                                                      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.






                                                      share|improve this answer




























                                                        -2














                                                        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.






                                                        share|improve this answer


























                                                          -2












                                                          -2








                                                          -2







                                                          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.






                                                          share|improve this answer













                                                          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.







                                                          share|improve this answer












                                                          share|improve this answer



                                                          share|improve this answer










                                                          answered Aug 30 '15 at 16:27









                                                          AlidorAlidor

                                                          1




                                                          1























                                                              -2














                                                              What about:



                                                              int sgn = x/fabs(x);


                                                              it should work out pretty good.






                                                              share|improve this answer





















                                                              • 5





                                                                What happens when x == 0.0 ?

                                                                – Paul R
                                                                Jun 20 '17 at 7:30






                                                              • 1





                                                                and the performance would be pretty bad, too

                                                                – phuclv
                                                                Jun 30 '18 at 3:26
















                                                              -2














                                                              What about:



                                                              int sgn = x/fabs(x);


                                                              it should work out pretty good.






                                                              share|improve this answer





















                                                              • 5





                                                                What happens when x == 0.0 ?

                                                                – Paul R
                                                                Jun 20 '17 at 7:30






                                                              • 1





                                                                and the performance would be pretty bad, too

                                                                – phuclv
                                                                Jun 30 '18 at 3:26














                                                              -2












                                                              -2








                                                              -2







                                                              What about:



                                                              int sgn = x/fabs(x);


                                                              it should work out pretty good.






                                                              share|improve this answer















                                                              What about:



                                                              int sgn = x/fabs(x);


                                                              it should work out pretty good.







                                                              share|improve this answer














                                                              share|improve this answer



                                                              share|improve this answer








                                                              edited May 22 '17 at 13:56









                                                              gsamaras

                                                              51.2k24100186




                                                              51.2k24100186










                                                              answered May 22 '17 at 13:46









                                                              DanielDaniel

                                                              1




                                                              1








                                                              • 5





                                                                What happens when x == 0.0 ?

                                                                – Paul R
                                                                Jun 20 '17 at 7:30






                                                              • 1





                                                                and the performance would be pretty bad, too

                                                                – phuclv
                                                                Jun 30 '18 at 3:26














                                                              • 5





                                                                What happens when x == 0.0 ?

                                                                – Paul R
                                                                Jun 20 '17 at 7:30






                                                              • 1





                                                                and the performance would be pretty bad, too

                                                                – phuclv
                                                                Jun 30 '18 at 3:26








                                                              5




                                                              5





                                                              What happens when x == 0.0 ?

                                                              – Paul R
                                                              Jun 20 '17 at 7:30





                                                              What happens when x == 0.0 ?

                                                              – Paul R
                                                              Jun 20 '17 at 7:30




                                                              1




                                                              1





                                                              and the performance would be pretty bad, too

                                                              – phuclv
                                                              Jun 30 '18 at 3:26





                                                              and the performance would be pretty bad, too

                                                              – phuclv
                                                              Jun 30 '18 at 3:26











                                                              -5














                                                              use:



                                                              `#define sgn(x) (x<0)` 


                                                              for example:



                                                              `if(sng(n)) { etc ....}`


                                                              Or you may want to use some elaborated code, but casting first:



                                                              inline bool sgn_long(long x)
                                                              {
                                                              return ((x<0)? true: false);
                                                              }






                                                              share|improve this answer



















                                                              • 1





                                                                The question was about a function that returns -1/0/+1 for negative/zero/positive numbers.

                                                                – Martin R
                                                                Nov 17 '17 at 10:03
















                                                              -5














                                                              use:



                                                              `#define sgn(x) (x<0)` 


                                                              for example:



                                                              `if(sng(n)) { etc ....}`


                                                              Or you may want to use some elaborated code, but casting first:



                                                              inline bool sgn_long(long x)
                                                              {
                                                              return ((x<0)? true: false);
                                                              }






                                                              share|improve this answer



















                                                              • 1





                                                                The question was about a function that returns -1/0/+1 for negative/zero/positive numbers.

                                                                – Martin R
                                                                Nov 17 '17 at 10:03














                                                              -5












                                                              -5








                                                              -5







                                                              use:



                                                              `#define sgn(x) (x<0)` 


                                                              for example:



                                                              `if(sng(n)) { etc ....}`


                                                              Or you may want to use some elaborated code, but casting first:



                                                              inline bool sgn_long(long x)
                                                              {
                                                              return ((x<0)? true: false);
                                                              }






                                                              share|improve this answer













                                                              use:



                                                              `#define sgn(x) (x<0)` 


                                                              for example:



                                                              `if(sng(n)) { etc ....}`


                                                              Or you may want to use some elaborated code, but casting first:



                                                              inline bool sgn_long(long x)
                                                              {
                                                              return ((x<0)? true: false);
                                                              }







                                                              share|improve this answer












                                                              share|improve this answer



                                                              share|improve this answer










                                                              answered Nov 15 '17 at 22:25









                                                              Roberto TUNINETTIRoberto TUNINETTI

                                                              1




                                                              1








                                                              • 1





                                                                The question was about a function that returns -1/0/+1 for negative/zero/positive numbers.

                                                                – Martin R
                                                                Nov 17 '17 at 10:03














                                                              • 1





                                                                The question was about a function that returns -1/0/+1 for negative/zero/positive numbers.

                                                                – Martin R
                                                                Nov 17 '17 at 10:03








                                                              1




                                                              1





                                                              The question was about a function that returns -1/0/+1 for negative/zero/positive numbers.

                                                              – Martin R
                                                              Nov 17 '17 at 10:03





                                                              The question was about a function that returns -1/0/+1 for negative/zero/positive numbers.

                                                              – Martin R
                                                              Nov 17 '17 at 10:03


















                                                              draft saved

                                                              draft discarded




















































                                                              Thanks for contributing an answer to Stack Overflow!


                                                              • Please be sure to answer the question. Provide details and share your research!

                                                              But avoid



                                                              • Asking for help, clarification, or responding to other answers.

                                                              • Making statements based on opinion; back them up with references or personal experience.


                                                              To learn more, see our tips on writing great answers.




                                                              draft saved


                                                              draft discarded














                                                              StackExchange.ready(
                                                              function () {
                                                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1903954%2fis-there-a-standard-sign-function-signum-sgn-in-c-c%23new-answer', 'question_page');
                                                              }
                                                              );

                                                              Post as a guest















                                                              Required, but never shown





















































                                                              Required, but never shown














                                                              Required, but never shown












                                                              Required, but never shown







                                                              Required, but never shown

































                                                              Required, but never shown














                                                              Required, but never shown












                                                              Required, but never shown







                                                              Required, but never shown







                                                              Popular posts from this blog

                                                              Guess what letter conforming each word

                                                              Port of Spain

                                                              Run scheduled task as local user group (not BUILTIN)