67
\$\begingroup\$

Given a number N, output the sign of N:

  • If N is positive, output 1
  • If N is negative, output -1
  • If N is 0, output 0

N will be an integer within the representable range of integers in your chosen language.

\$\endgroup\$
  • 45
    \$\begingroup\$ This is a trivial challenge with a lot of trivial solutions. There are however some non-trivial solutions too. To voters: Please read the first sentence of this meta post before upvoting builtin functions. \$\endgroup\$ – Stewie Griffin Dec 20 '16 at 10:10
  • 8
    \$\begingroup\$ This could probably use a leaderboard. \$\endgroup\$ – Martin Ender Dec 20 '16 at 11:13
  • 2
    \$\begingroup\$ @MrLister upvote how you want, but really you should look for creativity instead of code length. \$\endgroup\$ – FlipTack Dec 28 '16 at 20:13
  • 3
    \$\begingroup\$ @FlipTack Oh, I thought it was codegolf. \$\endgroup\$ – Mr Lister Dec 28 '16 at 20:23
  • 3
    \$\begingroup\$ @MrLister that's the objective winning criterion. but does it really take more effort to type s for a sign builtin, or use some clever bitshifting/maths to work it out? Have a look at this meta post \$\endgroup\$ – FlipTack Dec 28 '16 at 20:25

141 Answers 141

1
\$\begingroup\$

FORTRAN 77, 87 bytes

      READ*,I
      IF(I)1,2,3
1     PRINT*,-1
2     PRINT*,0
3     PRINT*,1
      END

It is a nice use for the "harmful" arithmetic if statement. Unfortunately, this lovely feature was obsolete in Fortran 90 and posterior versions.

Curiously, gfortran can't handle with this arithmetic if, even if I save the file with .f extension. Therefore, I could not test this code.

\$\endgroup\$
1
\$\begingroup\$

Whitespace, 73 72 68 bytes

[S S S T    N
_Push_1][S N
S _Duplicate_1][S N
S _Duplicate_1][T   N
T   T   _Read_as_integer][T T   T   _Retrieve][S N
S _Duplicate_input][S N
S _Duplicate_input][N
T   T   N
_If_negative_jump_to_Label_NEGATIVE][N
T   S S N
_If_0_jump_to_Label_ZERO][S N
T   _Swap_top_two][T    N
S T _Print_as_integer][N
N
N
_Exit][N
S S N
_Create_Label_NEGATIVE][S S T   T   N
_Push_-1][T N
S T _Print_as_integer][N
N
N
_Exit][N
S S S N
_Create_Label_ZERO][T   N
S T _Print_as_integer]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Example runs:

Positive:

Command    Explanation                   Stack           Heap     STDIN    STDOUT    STDERR

SSSN       Push 1                        [1]             {}
SNS        Duplicate top (1)             [1,1]           {}
SNS        Duplicate top (1)             [1,1,1]         {}
TNTT       Read STDIN as integer         [1,1]           {1:5}    5
TTT        Retrieve at heap 1            [1,5]           {1:5}
SNS        Duplicate top (5)             [1,5,5]         {1:5}
SNS        Duplicate top (5)             [1,5,5,5]       {1:5}
NTTN       If neg.: Jump to Label_NEG    [1,5,5]         {1:5}
NTSSN      If 0: Jump to Label_ZERO      [1,5]           {1:5}
SNT        Swap top two                  [5,1]           {1:5}
TNST       Print top as integer          [5]             {1:5}             1
NNN        Exit                          [5]             {1:5}

Program stops with an error: Label does not exist
Try it online (with raw spaces, tabs and new-lines only).

Zero:

Command    Explanation                   Stack           Heap     STDIN    STDOUT    STDERR

SSSN       Push 1                        [1]             {}
SNS        Duplicate top (1)             [1,1]           {}
SNS        Duplicate top (1)             [1,1,1]         {}
TNTT       Read STDIN as integer         [1,1]           {1:0}    0
TTT        Retrieve at heap 1            [1,0]           {1:0}
SNS        Duplicate top (0)             [1,0,0]         {1:0}
SNS        Duplicate top (0)             [1,0,0,0]       {1:0}
NTTN       If neg.: Jump to Label_NEG    [1,0,0]         {1:0}
NTSSN      If 0: Jump to Label_ZERO      [1,0]           {1:0}
NSSSN      Create Label_ZERO             [1,0]           {1:0}
TNST       Print top as integer          [1]             {1:0}              0
                                                                                     error

Program stops with an error: No exit defined
Try it online (with raw spaces, tabs and new-lines only).

Negative:

Command    Explanation                   Stack           Heap     STDIN    STDOUT    STDERR

SSSN       Push 1                        [1]             {}
SNS        Duplicate top (1)             [1,1]           {}
SNS        Duplicate top (1)             [1,1,1]         {}
TNTT       Read STDIN as integer         [1,1]           {1:-5}   -5
TTT        Retrieve at heap 1            [1,-5]          {1:-5}
SNS        Duplicate top (-5)            [1,-5,-5]       {1:-5}
SNS        Duplicate top (-5)            [1,-5,-5,-5]    {1:-5}
NTTN       If neg.: Jump to Label_NEG    [1,-5,-5]       {1:-5}
NSSN       Create Label_NEG              [1,-5,-5]       {1:-5}
SSTTN      Push -1                       [1,-5,-5,-1]    {1:-5}
TNST       Print top as integer          [1,-5,-5]       {1:-5}            -1
NNN        Exit                          [1,-5,-5]       {1:-5}

Program stops with an error: Label does not exist
Try it online (with raw spaces, tabs and new-lines only).

\$\endgroup\$
1
\$\begingroup\$

Brain-Flak, 40 38 bytes

{<>(())<>{(([{}[]]))<>([{}])<>}}<>({})

Try it online!

A bit longer at 50 bytes, but here's a version that acts only on the top value of the stack, returning 0, -1 or 1 depending on the sign of the number.

({<({}([(())])){({}([{}([{}])]))}{}{}>{}(<()>)}{})

How it Works:

{ If number is not 0
 <>(())<> Push 1 to the other stack as the sign
 { While number != 0
  (([{}[]])) Push -(number+stack height) twice
  <>([{}])<> Negate sign, alternating it between -1 and 1
 } end while
}<>({}) Switch to other stack and force a 0 if the stack is empty
\$\endgroup\$
1
\$\begingroup\$

TIS -n 1 1, 57 bytes

@0
MOV UP ACC
ADD 998
SUB 998
SUB 998
ADD 998
MOV ACC ANY

Try it online!

The integral data type supported by TIS ranges from -999 to 999. Any value in input, code, or calculations is silently coerced (clamped) into that range (instead of truncation, overflowing, etc.).

So, by adding 998 to any number, then subtracting the same amount, it becomes 1 is it was positive, and stays untouched otherwise. We then do the same to coerce all negative numbers to -1.

We need to subtract across two separate operations, due to the coercion mentioned above.

If you are familiar with TIS-100, you will be used to a 3x4 array of computational nodes, however, this solutions only uses one such node, nominally taking input from above and giving it below.

\$\endgroup\$
0
\$\begingroup\$

Pyke, 5 bytes

0'<>-

Try it here!

0'<>  - 0<input, 0>input
    - - ^-^
\$\endgroup\$
0
\$\begingroup\$

Loader, 61+44+1=106 bytes

Main module, 61 bytes

readline 0
set B =48
load a
set B =45
set K -1
load a
print 1

Module a, 44 bytes

decr B
decr *0
B:load a
~*0:print K
~*0:exit
\$\endgroup\$
0
\$\begingroup\$

PARI/GP, 4 bytes

sign

Another boring built-in.

\$\endgroup\$
0
\$\begingroup\$

GameMaker Language, 22 bytes

return sign(argument0)

Alternative solutions:

return median(1,argument0,-1)
a=argument0 return (a>0)-(a<0)
a=argument0 return max(-1,min(a,1))
a=argument0 if a return a/abs(a)return 0
\$\endgroup\$
0
\$\begingroup\$

Clojure, 24 bytes

#(cond(> % 0)1(< % 0)-1 0 0)

An anonymous function that checks for being greater than 0, less than 0, then defaults on 0 if neither is true. cond acts as (and is a macro resulting in) an if-else tree. Unfortunately, it requires an even number of arguments, so I had to waste 2 bytes by adding an extra number to mean true to default on.

Ungolfed:

(defn sign [n]
  (cond
    (> n 0) 1
    (< n 0) -1
    :else 0))
\$\endgroup\$
0
\$\begingroup\$

BotEngine, 7x17=119

v #  #0123456789
>Ie~>SSSSSSSSSSS
    ^ <<<<<<<<<<P
  PeeS-        1e
 Pe1-S0123456789
  0  > SSSSSSSSS
       >>>>>>>>>^
\$\endgroup\$
0
\$\begingroup\$

F#, 31 9 bytes

Math.Sign

(Saved 22 bytes thanks to @pmbanka's advice :))

fun(i:int)->System.Math.Sign(i)

I was about to post a C# solution.. but it already exists :(

So I decided to have some fun with F#!!

//a solution with 24 bytes, but you have to put `open System` into the file. 
//Not sure if that would be valid...

fun(i:int)->Math.Sign(i)
\$\endgroup\$
  • \$\begingroup\$ I think you don't need to wrap a function inside a lambda. The answer could be as simple as System.Math.Sign, with example usage System.Math.Sign 2 BTW, in F# you don't need to wrap a single argument in a parentheses, saving a byte. And as a side note, I think that C# not counting using System; is a bit weird, but maybe these are the rules here... In such case, assume open System is there as well. \$\endgroup\$ – pmbanka Dec 21 '16 at 11:19
  • \$\begingroup\$ I'm not very familiar with F#, but unless System is imported by default, you have to use the fully-qualified name System.Math.Sign. \$\endgroup\$ – Mego Dec 23 '16 at 14:47
0
\$\begingroup\$

Go, 49 bytes

func s(x int)int{return(x>>63)|int(uint(-x)>>63)}

Note: this won't work on the playground until Go 1.8 is released due to this bug: https://github.com/golang/go/issues/16203

\$\endgroup\$
  • \$\begingroup\$ Possibly doesn't work for the minimum integer (-1<<63)? \$\endgroup\$ – Neil Dec 21 '16 at 10:30
  • \$\begingroup\$ @Neil nope! Should work for all 64 bit integers. \$\endgroup\$ – Eric Lagergren Dec 21 '16 at 16:12
  • \$\begingroup\$ Oh, I see now, you just get -1|1 in that case, which is still -1. \$\endgroup\$ – Neil Dec 21 '16 at 20:13
0
\$\begingroup\$

OCaml, 4 bytes

sign

Didn't even know there was a built-in for this. Alternative 18 bytes solution:

fun x->compare x 0
\$\endgroup\$
0
\$\begingroup\$

Stacked, 4 bytes

sign

Takes input from top of stack. Bonafide function:

$sign

Shortest non-builtin so far:

:0>\0<-

Which does:

:0>\0<-                        stack: [..., n]
:        duplicate TOS         stack: [..., n, n]
 0       push 0                stack: [..., n, n, 0]
  >      pop n,0 and push n>0  stack: [..., n, n>0]
   \     switch top two        stack: [..., n>0, n]
    0    push 0                stack: [..., n>0, n, 0]
     <   pop n,0 and push n<0  stack: [..., n>0, n<0]
      -  subtract top two      stack: [..., (n>0)-(n<0)]

Surround with [] to be a function.

\$\endgroup\$
0
\$\begingroup\$

TI-Basic, 11 bytes

:Input A
:A>0
:Ans-A<0

Reads from variable A.

:A>0            // Reads from A, returns 0 or 1
:Ans-A<0.   // Computes A<0 first, then subtracts from previous result. Implicit print.
\$\endgroup\$
  • \$\begingroup\$ To be fair, the other TI-Basic Answer used Ans for input, which decreases his code by 3 bytes. You could add 3 bytes to both of ours through Input A: then use the same metric. \$\endgroup\$ – Julian Lachniet Dec 23 '16 at 13:30
0
\$\begingroup\$

JavaScript (ES6), 14 bytes

No conditionals, no Math lib usage

x=>(x>0)-(x<0)

Explanation

x > 0 is true/false for positives/non-positives and cast to number (1/0) in case for subtraction. x < 0 is analogous for negatives, so we end up with 1-0 for positives, 0-0 for zero and 0-1 for negatives.

\$\endgroup\$
0
\$\begingroup\$

Math++, 28 bytes

?>a
3+2*!a>$
a/sqrta*a
0>$
0
\$\endgroup\$
  • \$\begingroup\$ Could you link to an interpreter? \$\endgroup\$ – Mego Dec 23 '16 at 15:01
0
\$\begingroup\$

Python 2, 26 Bytes

b=input()
print(b>0)-(b<0)
\$\endgroup\$
0
\$\begingroup\$

Factor, 71 bytes

Expects a string.

[ 0 swap nth { { CHAR: - [ -1 ] } { CHAR: 0 [ 0 ] } [ drop 1 ] } case ]

ungolfed:

: sign-of ( x -- y ) 0 swap nth
  {
    { CHAR: - [ -1 ] }
    { CHAR: 0 [ 0 ] }
    [ drop 1 ]
  } case ;
\$\endgroup\$
0
\$\begingroup\$

Python 3, 29 bytes

lambda a:(a>>31)|a

Tested--it works. EDIT: Sigh...8 more bytes because the previous solution was taken. EDIT 2: Fixed a bug. EDIT 3: Knocked 10 bytes off. Now this is shorter than the one that was already taken!

\$\endgroup\$
  • \$\begingroup\$ This solution already exists \$\endgroup\$ – Mego Dec 23 '16 at 21:39
  • \$\begingroup\$ Darn it! Should I change my solution? \$\endgroup\$ – python-b5 Dec 23 '16 at 21:43
  • \$\begingroup\$ Yes, please. Either delete it, or edit it to be distinct. \$\endgroup\$ – Mego Dec 23 '16 at 21:43
  • \$\begingroup\$ You can keep your original answer if you wish, duplicate answers are allowed. \$\endgroup\$ – xnor Dec 25 '16 at 8:54
  • \$\begingroup\$ This fails on positive inputs. \$\endgroup\$ – isaacg Jan 11 '17 at 8:12
0
\$\begingroup\$

MS Excel, 9 Bytes

Takes Input from cell A1.

=SIGN(A1)
\$\endgroup\$
0
\$\begingroup\$

Symbolic Python, 24 bytes

Like many other solutions, this uses the formula s(x) = (x > 0) - (x < 0). Note that this solution is non-competing as the language postdates the challenge.

__={}>{}
_=(_>__)-(_<__)

Symbolic Python is a restricted source version of Python: all alphanumeric characters are banned.

The interpreter automatically puts input in the variable _. From there, the code works like so:

  • {}>{} generates the value False. This is then assigned to the variable __. Although it's technically a boolean, we use this as the integer 0:
  • (_>__) checks whether the input is greater than 0. (_<__) checks whether the input is smaller than 0. These booleans are then interpreted as integers, and the first is subtracted from the second.
  • The result of this is put in the variable _, which is automatically printed after execution.
\$\endgroup\$
0
\$\begingroup\$

Ruby, 19 bytes

Not quite as golfy as my other answer.

->n{("%+b"%n)[0,2]}

Outputs -1, +0, +1

\$\endgroup\$
0
\$\begingroup\$

Japt, 1 byte (non-competing)

g

Try it online!

\$\endgroup\$
0
\$\begingroup\$

8th, 40 bytes

The following code has the same behaviour of 8th's builtin word n:sgn

: f dup 0; 0 n:> if 1 else -1 then nip ;

Explanation of word f

: f \ n -- -1|0|1
  dup     \ Duplicate input
  0;      \ Check if number is 0. If true, leave 0 on TOS and exit from word
  0 n:>   \ Check if positive
  if 1    \ Return 1 if positive
  else -1 \ Return -1 if negative
  then
  nip     \ Get rid of input
; 

Testing and Output

ok> 42 f .
1
ok> -42 f .
-1
ok> 0 f .
0
\$\endgroup\$
0
\$\begingroup\$

tcl 24 23

puts [expr $n<0?-1:$n>0]

Thanks to http://wiki.tcl.tk/819 page authors!

UPDATE: based on the C answer https://codegolf.stackexchange.com/a/103831/29325

puts [expr !!$n|$n>>31]

can be run on http://rextester.com/live/BKGZ8868 where i tested with -9,0,9

\$\endgroup\$
0
\$\begingroup\$

Fourier, 18 17 bytes

I~A<0{1}{`-`}A/Ao

Try it on FourIDE!

Explanation pseudocode:

A = Input
If A<0 Then
    Print "-"
End If
Print A/A
\$\endgroup\$
0
\$\begingroup\$

MY, 3 bytes

Hex:

 1A #Input integer
 2A #Sign function
 27 #Output (trailing newline)
\$\endgroup\$
0
\$\begingroup\$

Excel VBA, 10 Bytes

Anonymous VBE immediate window function that takes input from cell [A1] and outputs -1,0 or 1 to the VBE immediate window

?Sgn([A1])
\$\endgroup\$
0
\$\begingroup\$

Common Lisp, 39 bytes

(defun f(x)(if(= x 0)0(if(> x 0)1 -1)))

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.