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

4
\$\begingroup\$

05AB1E, 3 bytes

0.S

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Labyrinth, 8 bytes

1,_47-%!

Try it online!

I'm posting this as a separate answer because my other Labyrinth answer is based on arithmetic on the actual numerical input value, whereas this mostly ignores the number and works with the character code of the first character instead.

Explanation

So yeah, this reads the first character code which is either 45 (-, which should yield -1), 48 (0, which should yield 0) or 49 to 57 (1-9, which should yield 1). This mapping can be accomplished via the simple formula 1 % (x - 47). To see why this works, here is the breakdown of the code for 3 different examples:

Code    Comment             Example -5      Example 0       Example 5
1       Push 1.             [1]             [1]             [1]
,       Read character.     [1 45]          [1 48]          [1 53]
_47-    Subtract 47.        [1 -2]          [1 1]           [1 6]
%       Modulo.             [-1]            [0]             [1]
!       Print.              []              []              []

The instruction pointer then hits a dead end, turns around and terminates when % now attempts a division by zero.

Another simple computation that works:

x -= 46
x %= x-1
\$\endgroup\$
4
\$\begingroup\$

Turing Machine code, 65 bytes

0 0 0 * halt
0 - - r 2
0 * 1 r 3
2 * 1 r 3
3 * _ r 3
3 _ _ * halt

Try it online.

\$\endgroup\$
  • \$\begingroup\$ Could you link to an interpreter? \$\endgroup\$ – Mego Dec 23 '16 at 15:00
  • \$\begingroup\$ couldn't you output using halt state here :P \$\endgroup\$ – ASCII-only Apr 12 at 7:19
4
\$\begingroup\$

Brain-Flak, 48 46 40 bytes

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

Try it Online

Explanation

{                                }{}({}) #Do nothing if zero
   ({}<([()])>)                          #Put a -1 under input
 ([            ]<>(()))                  #Put 1 and a negative copy of input on the off stack
                       {        }        #Until zero
                        ({}())           #Increment
                              <>         #Swap
\$\endgroup\$
4
\$\begingroup\$

Hexagony, 13 bytes

?</!~/~@$\!@

Expanded:

  ? < /
 ! ~   /
~ @ $ \ !
 @ . . .
  . . .

Try it online!

Hexagony truthy/falsiness for numbers checks based on being positive or not. This makes singling out zero a bit tricky, so we check if a number and its negation are both non-positive to check for zero. Uses the unprintable character 0x01 to literally store 1 in a memory edge to save a byte zeroing the edge first. In the expanded version it is between the ~ and the / on the second line.

Breakdown:

For positive numbers the code is very simple. We start at the top left moving eastward, then take the fork to the right. The rest of the program is "linear" along the surface of the code, giving: ?<0x01\.!@ where both \ and . are no-ops. 0x01 sets the current memory edge to 1 and then ! prints that and @ ends the program.

For negative numbers and zero, we start the same but turn left at the <. This leads us back around to the \ but this time approaching from the southwest. This time it acts as a mirror and redirects the instruction pointer westward. The $ allows us to skip the program-ending @. Next we hit ~ which negates the value that we read in. If the number was negative it is now positive, and if it was zero it is still not positive.

When hitting the edge of the hexagon we wrap to the right if the value was positive and to the left if the value was negative or zero. Negative numbers will then wrap to the right and begin moving westwards from the top right. Hitting some mirrors leads us to a familiar looking path starting with the edge being set to 1. Then ~ negates it and ! prints giving -1. We wrap around and hit the other @.

Zero will instead wrap to the bottom, which has nothing but no-ops. Then it wraps back to the middle and is printed by !. Then some mirrors redirect us to the @ to end the program.

\$\endgroup\$
4
\$\begingroup\$

Excel, 8 bytes

=Sign(n)

Pretty basic, but the only language I feel complete confidence in.

Without a builtin!

Excel, 23 bytes

=If(n>0,1,If(n<0,-1,0))

not so confident

Crystal Reports Formula (Noncompete), 24 bytes

IIF(n>0,1,IIF(n<0,-1,0))
\$\endgroup\$
4
\$\begingroup\$

Python 3, 20 bytes

Since Python 3 doesn't have access to cmp like Python 2 does, it's a little longer

lambda n:(n>0)-(n<0)
\$\endgroup\$
  • \$\begingroup\$ Practically the same as this answer: codegolf.stackexchange.com/a/103831/41805 \$\endgroup\$ – Cows quack Dec 21 '16 at 11:35
  • 1
    \$\begingroup\$ @KritixiLithos practically but it's also an entirely different llanguage \$\endgroup\$ – Dillanm Dec 21 '16 at 11:37
  • 1
    \$\begingroup\$ How about n//abs(n) for two bytes \$\endgroup\$ – Phlarx Dec 21 '16 at 21:28
  • 1
    \$\begingroup\$ @Dillanm ah, right. Didn't catch that, obvious in hindsight :P \$\endgroup\$ – Phlarx Dec 22 '16 at 16:16
  • 2
    \$\begingroup\$ @Dillanm You can, actually, but it's several bytes longer: n and n//abs(n) \$\endgroup\$ – Phlarx Dec 23 '16 at 16:19
4
\$\begingroup\$

Befunge 93, 14 13 bytes

Golfed off a byte by combining the 2 1s

1~50p :0`_.@.

Try it Online!

This one is interesting, as it takes the first character of the number and alters the code accordingly.

 ~50p         Stores the first character in the space (labeled <char> here)
1    <char>   If the number is negative, it performs subtraction, giving 1 - 0 == -1
              If it is 0, 0 is on top. If it is positive, a positive # will be.

 :0`_         This checks the top number to see if it is positive.
     .@       If it is <1, it is printed. (0 or -1)
1     @.      Otherwise, the IP loops back harmlessly, and prints 1
\$\endgroup\$
3
\$\begingroup\$

Mathematica, 28 bytes

Limit[2ArcTan@x#/Pi,x->∞]&

Mathematica, 30 bytes

2HeavisideTheta@#-1/._[_]->1/2&

Mathematica, 76 bytes

Round@Integrate[E^(2#+I t#)/(2+I t)/Pi,{t,-∞,∞},PrincipalValue->True]-1&

Just to be different :)

\$\endgroup\$
  • 2
    \$\begingroup\$ Median@{#,1,-1} and #~Min~1~Max~-1 if you want some more ideas ;) \$\endgroup\$ – Martin Ender Dec 20 '16 at 12:09
  • \$\begingroup\$ Personal challenge to you: find an implementation that's longer than 76 bytes, but fully golfed for its algorithm (can you be turned to the dark side?!). \$\endgroup\$ – Greg Martin Dec 20 '16 at 18:43
  • \$\begingroup\$ Can I take you up on this challenge? \$\endgroup\$ – Gabriel Benamy Dec 20 '16 at 23:29
  • \$\begingroup\$ Of course! .. :) \$\endgroup\$ – Greg Martin Dec 21 '16 at 0:13
3
\$\begingroup\$

Forth, 22 bytes

Golfed

: S dup 0< swap 0> - ;

Test

: S dup 0< swap 0> - ;  ok

0 S . 0  ok
1 S . 1  ok
-1 S . -1  ok
12345 S . 1  ok
-12345 S . -1  ok

Try It Online !

\$\endgroup\$
  • \$\begingroup\$ Nice. I was going to post something similar that I wrote several months ago. \$\endgroup\$ – mbomb007 Dec 20 '16 at 22:38
3
\$\begingroup\$

x86_64 machine language on Linux, 13 bytes

 0:   31 c0                   xor    %eax,%eax
 2:   85 ff                   test   %edi,%edi
 4:   0f 9f c0                setg   %al
 7:   c1 ef 1f                shr    $0x1f,%edi
10:   29 f8                   sub    %edi,%eax
12:   c3                      retq

The input (first function parameter) is passed into %edi. To try it out, compile and run the following C program

#include<stdio.h>
#include<stdlib.h>
#define s(x) ((int(*)(int))"\x31\xc0\x85\xff\xf\x9f\xc0\xc1\xef\x1f\x29\xf8\xc3")(x)
int main(){
  printf( "%d %d %d\n", s(-5), s(0), s(44) );
}
\$\endgroup\$
  • \$\begingroup\$ I'm a bit surprised that x86 doesn't have a builtin for sign. \$\endgroup\$ – Mego Dec 23 '16 at 15:00
  • \$\begingroup\$ Casting a C string to a function pointer? That's nasty. \$\endgroup\$ – Nic Hartley Dec 26 '16 at 1:08
  • \$\begingroup\$ @QPaysTaxes, that is also an elegant/horrifying way to make lambdas in C qsort(a,sizeof a/4,4,"\x8b\7+\6\xc3"); \$\endgroup\$ – ceilingcat Dec 29 '16 at 5:17
  • \$\begingroup\$ I got virtually the same solution in a language I created that is based off of C lambdas. What C code did you use to generate this machine code? \$\endgroup\$ – MD XF Mar 27 '18 at 18:50
3
\$\begingroup\$

Plain English 101 81 bytes

To put a n number's sign into a s number:
Get the sign of the n returning the s.

Ungolfed version:

To put a number's sign into another number:
  Get the sign of the number returning the other number.

Either version can be used to golf the client code -- and make the client code more readable. For example, the following line of code displays a Windows message box containing the number -1 in the message body:

Debug -456's sign.

The Plain English IDE is available at github.com/Folds/english. The IDE runs on Windows. It compiles to 32-bit x86 code.

\$\endgroup\$
  • 1
    \$\begingroup\$ ... I don't think that the Ungolfed version was really necessary \$\endgroup\$ – Taylor Scott Aug 1 '17 at 18:36
3
\$\begingroup\$

Haskell, 23 characters

A true approach, not using built-ins but function composition (the dot):

(1-).fromEnum.compare 0

(or with more space)

(1-) . fromEnum . compare 0

Explanation:

compare 0 : partially applying the compare function to
                the first argument 0 results in a function which takes
                a number and compares it to 0. 
                  (compare 0) n = compare 0 n =
                      LT    : if 0 < n
                      EQ    : if 0 = n
                      GT    : if 0 > n
fromEnum  : it maps LT to 0, EQ to 1 and GT to 2
(1-)      : n -> 1 - n
\$\endgroup\$
  • 1
    \$\begingroup\$ You can save 3 bytes by replacing pred with (1-) which allows you to replace (`compare`0) with compare 0. \$\endgroup\$ – 0 ' Oct 20 '17 at 7:27
3
\$\begingroup\$

LOLCODE, 191 bytes

HAI 1.3
I HAS A J ITZ A NUMBR
GIMMEH J
BIGGR OF J AN 0, O RLY?
	YA RLY
		VISIBLE "1"
	NO WAI
		BOTH SAEM "0" AN J, O RLY?
			YA RLY
				VISIBLE "0"
			NO WAI
				VISIBLE "-1"
	OIC
OIC
KTHXBYE

Try it online!

\$\endgroup\$
  • \$\begingroup\$ This is surprisingly readable. \$\endgroup\$ – iamnotmaynard Nov 21 '17 at 18:17
  • \$\begingroup\$ @iamnotmaynard funny right? \$\endgroup\$ – FantaC Nov 21 '17 at 19:31
3
\$\begingroup\$

Hexagony, 18 15 bytes

~.?>.)<<!!.&,.@

Try it online!

n > 0

  ~ . ?
 . . . .
< . ! . .
 , . @ .
  . . .

n == 0

  ~ . ?
 > . ) <
< . ! . &
 . . @ .
  . . .

n < 0

  ~ . ?
 > . ) <
< ! . . .
 , . @ .
  . . .

Abuses the same EOF trick used in Jo Kings answer.

Sadly I currently don't have access to these neat visual tools used in other solutions.

\$\endgroup\$
2
\$\begingroup\$

Clojure, 14 bytes

#(compare % 0)

This uses the built-in compare function of clojure: it returns a 1 if the first arg is greater than the second arg, 0 if it's equal, and -1 if it's smaller.

Usage:

(#(...) {number})
\$\endgroup\$
2
\$\begingroup\$

Haskell, 6 bytes

signum

Just a boring built-in.

\$\endgroup\$
2
\$\begingroup\$

Perl 6, 9 bytes

+(*cmp 0)

Try it online!

Explanation:

+(     # turn into a number

  *    # Whatever (input)
  cmp  # compared to
  0    # 0

)
\$\endgroup\$
2
\$\begingroup\$

CJam, 1 byte

g

Try it online!

Another built-in, just for the sake of completeness.

\$\endgroup\$
2
\$\begingroup\$

Wonder, 4 bytes

sign

Usage:

sign 1

Builtin.

Bonus solution (no builtin), 7 bytes

tt cmp0

Usage:

(tt cmp0)5

Uses a compare function with 0.

\$\endgroup\$
2
\$\begingroup\$

Javascript, 18 bytes

x=>x/Math.abs(x)|0

x/Math.abs(x) is always 1 if x is positive and -1 if x is negative. If x is 0, it returns Nan, which we transform to 0 with the |0 bit.

\$\endgroup\$
2
\$\begingroup\$

Gema, 9 characters

Just a rewrite of Jordan's Sed solution.

0=0
<D>=1

Sample run:

bash-4.3$ gema '0=0;<D>=1' <<< $'-303\n-12\n-5\n0\n1\n20\n404'
-1
-1
-1
0
1
1
1

Gema, 19 characters

*=@cmpn{*;0;-1;0;1}

Posted just because Gema has a nice function for this task:

@cmpn{number;number;less-value;equal-value;greater-value}
Compare numbers.

Sample run:

bash-4.3$ gema '*=@cmpn{*;0;-1;0;1}' <<< -303
-1

bash-4.3$ gema '*=@cmpn{*;0;-1;0;1}' <<< 0
0

bash-4.3$ gema '*=@cmpn{*;0;-1;0;1}' <<< 404
1
\$\endgroup\$
2
\$\begingroup\$

Batch, 23 bytes

@cmd/cset/a"%1>>31|!!%1

>>31 evaluates to -1 if the input is negative and 0 if it is positive, while !! evaluates to 1 if it is nonzero and 0 if it is zero, so we just have to bitwise OR the two results together.

\$\endgroup\$
2
\$\begingroup\$

Java 1.8, 11 bytes

Math.signum

In the comments, some people pointed out that this might not technically be valid, if so, here's another version at 12 bytes:

Math::signum
\$\endgroup\$
  • \$\begingroup\$ This is not a full program neither an (anonymous) function, but rather just a code excerpt, which can not be reused directly, so I guess this does not qualify. \$\endgroup\$ – zeppelin Dec 20 '16 at 21:29
  • 3
    \$\begingroup\$ It is technically a function, just referencing an already existing one, you can call it the same way as an anonymous function, but I don't know if such solutions are/should be allowed. \$\endgroup\$ – nyuszika7h Dec 20 '16 at 22:15
  • \$\begingroup\$ @zeppelin From everything I've seen, this is as acceptable as a loose anonymous function. \$\endgroup\$ – Carcigenicate Dec 20 '16 at 22:22
  • \$\begingroup\$ It would be acceptable in a language like Javascript, where evaluating the expression like "Math.sign" will evaluate to a function reference, which you can then invoke or assign to a variable. But (AFAIK) 'Math.signum' does not make a valid standalone expression in Java. Probably you can replace it with a "method reference" (i.e. Math::signum) which will produce a Function<>, which can then be assigned to a variable and invoked, to make it qualify. \$\endgroup\$ – zeppelin Dec 21 '16 at 9:17
  • \$\begingroup\$ @nyuszika7h "you can call it the same way as an anonymous function" I don't think you can, w/o changing it to Math.signum(yourArgument), which involves rewriting the program text, and that is clearly not acceptable. (and you will still have to pass an argument in somehow). \$\endgroup\$ – zeppelin Dec 21 '16 at 9:18
2
\$\begingroup\$

brainfuck, 23 bytes

-<,
[
  [
    >-[-<]
    >
  ]
  ->[>+>]
]
<.

This takes a single byte from stdin and interprets it as a signed char, printing \xff for negative, \x00 for zero, and \x01 for positive.

Try it online.

Viewed as an unsigned char, we are checking whether it is greater than 127, with 0 as a special case. We can do the comparison by decrementing from 255 twice at a time.

\$\endgroup\$
  • \$\begingroup\$ Doing I/O as decimal strings could be fun too. \$\endgroup\$ – Mitch Schwartz Dec 21 '16 at 16:48
  • \$\begingroup\$ You could argue that all numbers in BF are positive, so ,>+. is a valid answer. \$\endgroup\$ – Esolanging Fruit Dec 22 '16 at 4:38
  • 1
    \$\begingroup\$ @Challenger5 Even if that were modified to handle zero, e.g. with ,[>+>]<., I don't think that could be argued as anything other than a loophole. \$\endgroup\$ – Mitch Schwartz Dec 22 '16 at 5:49
  • \$\begingroup\$ Definitely, but it's funny. \$\endgroup\$ – Esolanging Fruit Dec 22 '16 at 5:50
  • 1
    \$\begingroup\$ @Challenger5 That would be abusing native number types to trivialize the challenge. The solution Mitch has used (interpreting the input as an 8-bit two's complement integer) is valid, and the only valid way to do this in brainfuck other than interpreting decimal strings (unless there's another way and I'm not seeing it). \$\endgroup\$ – Mego Dec 23 '16 at 14:44
2
\$\begingroup\$

Python 3, 23 bytes

lambda n:n and n/abs(n)

I know I can make it shorter by doing (n>0) - (n<0), but everyone else seems do be doing that so I thought I would do something different.

\$\endgroup\$
  • \$\begingroup\$ Welcome to Programming Puzzles & Code Golf! If you replace / with //, you don't need to cast to int. \$\endgroup\$ – Dennis Dec 22 '16 at 3:01
  • \$\begingroup\$ Thank you! I just realised I dont even need to casting at all. I thought that if n == 0 it would evaluate to false so I would have to convert it to an int but it turns out it stays as 0. \$\endgroup\$ – Cormac Dec 22 '16 at 3:15
  • \$\begingroup\$ Right, that returns a float. Nothing wrong with that, I guess. \$\endgroup\$ – Dennis Dec 22 '16 at 3:18
  • \$\begingroup\$ Floats are acceptable here, since 1.0 == 1 and -1.0 == -1. Nice job using the rarely-used definition of the sign function as the derivative of the absolute value function (with f(0) = 0 explicitly defined)! \$\endgroup\$ – Mego Dec 23 '16 at 14:40
2
\$\begingroup\$

GNU sed, 17 15 14 bytes

-2 bytes thanks to zeppelin. -1 byte thanks to manatwork.

/^0/!s/\w\+/1/

Try it online!

\$\endgroup\$
2
\$\begingroup\$

GNU Sed, 19 bytes (20 counting the r flag)

/^0+$/b;s/[0-9]+/1/

(Using the -r flag)

Translation:

/^0+$/b;

If the number is zero, skip to the end of the script

s/[0-9]+/1/

Substitute any other numbers with 1. If it's negative the negative sign will remain too.

\$\endgroup\$
  • \$\begingroup\$ That's basically a duplicate of Jordan's solution (which is 14 bytes). \$\endgroup\$ – zeppelin Dec 24 '16 at 10:19
  • \$\begingroup\$ Oh. Damn. ☹ Should I remove mine then? \$\endgroup\$ – Claire Cavanaugh Dec 24 '16 at 16:38
  • \$\begingroup\$ Well, not sure what's the current policy on this (I guess that is described somewhere on Meta), but AFAIK you can keep your answer. \$\endgroup\$ – zeppelin Dec 24 '16 at 21:32
2
\$\begingroup\$

Befunge-93, 23 21 20 bytes

Thanks to @Mistah Figgins for saving me two three bytes

I'm sure this is further golfable. I'll look at it again in the morning.

&:#@!#._0`#@:#._1-.@

Try it online!

Only takes in one line of input for each run, but that's within spec, I guess.

\$\endgroup\$
  • \$\begingroup\$ Nice First Answer! Welcome to the site. \$\endgroup\$ – Sriotchilism O'Zaic Dec 25 '16 at 4:54
  • \$\begingroup\$ Is there a reason for the space between the . and _ ? Seems like you could save a byte. \$\endgroup\$ – MildlyMilquetoast Jan 4 '17 at 0:52
  • \$\begingroup\$ Also, you can move one character into the 2 "#@ #" to make "#@!#" instead of "!#@ #". Nice answer though! \$\endgroup\$ – MildlyMilquetoast Jan 4 '17 at 5:00
  • \$\begingroup\$ You can use the same trick on :#@ # -> #@:# as well. My goal whenever writing befunge 93/98 is no whitespace at all. (he says as his own submission is 7% whitespace) \$\endgroup\$ – MildlyMilquetoast Jan 6 '17 at 7:21
2
\$\begingroup\$

Acc!!, 50 49 bytes

N
Count i while 45/_ {
Write _
49
}
Write 48+_/49

Acc!! reads input from stdin one character code at a time. This program decides what to output simply based on the first character of the input:

  • If it's -, output -1
  • If it's 0, output 0
  • Otherwise, output 1

Since Acc!! is a very bare-bones language, we have to use a loop for a conditional and integer division for comparison.

Commented version

# Read a character code from input and store it in _ (the accumulator)
N
# If that character was a minus sign (ASCII 45), 45/_ will be 1 and this loop will run
# If that code was a digit (ASCII 48-57), 45/_ will be 0 and the loop will be skipped
Count i while 45/_ {
  # For negative numbers, output the minus sign
  Write _
  # Set the accumulator to ASCII code of 1 so we will break out of the loop and write a 1
  49
}
# If the input was 0 (ASCII 48), _/49 will be 0 and the next line will write a 0
# Otherwise, _/49 will be 1 and the next line will write a 1
Write 48+_/49
\$\endgroup\$
  • \$\begingroup\$ Clever - this is the first solution I've seen that takes advantage of the fact that you only need to look at the first byte to determine the output (when using string input). \$\endgroup\$ – Mego Dec 23 '16 at 14:58

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.