text:
Output the sign
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.
The Catalogue
The Stack Snippet at the bottom of this post generates the catalogue from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.
To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:
## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:
## Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:
## Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the snippet:
## [><>](https://esolangs.org/wiki/Fish), 121 bytes

/* Configuration */

var QUESTION_ID = 103822; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 8478; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];

  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '
' + c.body.replace(OVERRIDE_REG, '') + '
';
    });

    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    else console.log(body);
  });

  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;

    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    lang = jQuery(''+lang+'').text();

    languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
    if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body {
  text-align: left !important;
  display: block !important;
}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 500px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}

<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/all.css?v=ffb5d0584c5f">

Shortest Solution by Language

Language	User	Score

Leaderboard

	Author	Language	Size

{{PLACE}}	{{NAME}}	{{LANGUAGE}}	{{SIZE}}	Link

{{LANGUAGE}}	{{NAME}}	{{SIZE}}	Link

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.

This could probably use a leaderboard.

@MartinEnder I use the userscript, so there's a builtin leaderboard. If you want to add the stack snippet, feel free.

do we have to account for leading zeroes?

@DestructibleWatermelon No

Can the input be considered as a string?

@PaulPicard Sure.

With a challenge such as this, I'd only be impressed if there was an answer that used less than 1 byte. Say, 5 bits or something. That I would upvote.

@MrLister At that point, you end up with a golfing only language. Languages like Excel (ME!) can do it in at the minimum 8 bytes. (I think.....)

@MrLister upvote how you want, but really you should look for creativity instead of code length.

@FlipTack Oh, I thought it was codegolf.

@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

Retina, 9 bytes
[1-9].*
1

Try it online!
Replaces a non-zero digit and everything after it with 1. This leaves a potential leading - intact and changes all numbers except 0 itself to absolute value 1.

This is very clever :)

Does it work with scientific notation of integer numbers (such as 0.42e2)?

@EgorSkriptunoff No, but that's not a requirement.

Strictly speaking, there were not any guarantees that the number 42 will be provided only in its most simple form.

@EgorSkriptunoff it doesn't support Roman numerals either. Unless the challenge explicitly mentions a certain non-standard format that needs to be supported, the general assumption is the it's fine to deal with a single format that's natural in your language of choice.

Sorry, I don't know whether Retina have scientific numeral format for numeric literals or not.  But if it does, this format must also be supported.

@EgorSkriptunoff Retina has no concept of numbers whatsoever. It's a purely string-based language.

As this seems to be a golf of the regex, and not using a language feature, it should be fine so 8 bytes

@cairdcoinheringaahing try 1024.

@MartinEnder Ah yeah, the regex doesn't catch the trailing 0s does it? Rip

C (GCC), 24 23 22 18 bytes
Thanks to @aross and @Steadybox for saving a byte!
f(n){n=!!n|n>>31;}

Not guaranteed to work on all systems or compilers, works on TIO.

Nothing to sigh about; that solution is a classic!

@Adám I'm sighing because, you know, 23 bytes. And I don't know how this answer has most upvotes.

@betseg That is because upvotes on built-ins are now frowned upon.

Non-standard, but mostly works: use "n=" instead of return, result goes into same CPU register as input. Tried with GCC on Ubuntu.

Saving 1 byte with this return n>>16|!!n;

Size of int is compiler dependent, 16 won't work on most modern systems.

@GB Size of int is probably either 2 (16, x86) or 4 (32, x86_64) but remember, all that's needed is an architecture on which it is valid. This isn't Stack Overlflow, portability is not important.

I changed 16 to 31 to make it work with every int value on TIO. I think this makes everyone happy? :)

f(n){n=n>>31|!!n;} works too. But this is just a compiler quirk, not a language feature.

@GB Compiler quirks are perfectly valid, so long as it can be proven that there is a compiler in which the quirk works. Luckily, gcc has the quirk.

I think you can still save a byte with f(n){return!!n|n>>31;}. The space after the return is not needed this way.

In your TIO link you can move the main method to the footer. It looks nice and gives an accurate byte count.

I got a C answer down to 18 bytes (ᵔᴥᵔ) http://codegolf.stackexchange.com/a/104164/16513

@AlbertRenshaw I did the assignment thing with GCC, and I'm down to 18 bytes as well :). I used the assignment thing on GCC before btw, I just forgot on this answer.

So it's a contest to 17 bytes you want is it??

Mathematica, 4 bytes
Clip

How about not using the built-in Sign and still scoring 4 bytes? ;)
Clip with a single argument clips (or clamps) the input value between -1 and 1. Since the inputs will only be integers, this is the same as using Sign.

COW, 225 213 201 bytes
oomMOOmoOmoOmoOmoOMoOMoOmOomOomOoMoOMMMmoOMMMMOOMOomOo
mOoMOomoOmoOmoomOomOoMMMmoOmoOmoOMMMMOOOOOmoOMOoMOomOo
mOomOoMoOMMMmoOMMMMOOMOomOomOoMoOmoOmoOmoomoOmoomOomOo
mOomoomoOMOOmoOmoOmoOMOoMMMOOOmooMMMOOM

Try it online!
The way that this code works is that it determines the sign by alternating adding and subtracting bigger numbers, and seeing which one was the last one that worked.  Given any non-zero integer, first subtract 1, then add 2, then subtract 3, etc. and you'll eventually reach 0.  Keep track of your state by alternating adding and subtracting 2 to a value that starts off at 0.  For example:
-5  - 1  = -6  (current state: 0 + 2 = 2)
-6  + 2  = -4  (current state: 2 - 2 = 0)
-4  - 3  = -7  (current state: 0 + 2 = 2)
-7  + 4  = -3  (current state: 2 - 2 = 0)
-3  - 5  = -8  (current state: 0 + 2 = 2)
-8  + 6  = -2  (current state: 2 - 2 = 0)
-2  - 7  = -9  (current state: 0 + 2 = 2)
-9  + 8  = -1  (current state: 2 - 2 = 0)
-1  - 9  = -10 (current state: 0 + 2 = 2)
-10 + 10 =  0  (current state: 2 - 2 = 0)
value is now at 0.  state - 1 = 0 - 1 = -1
sign of original number is -1

When you're done, subtract 1 from your state and you get the sign, positive or negative.
If the original number is 0, then don't bother doing any of this and just print 0.
Detailed Explanation:
oom                                        ;Read an integer into [0]
MOO                                        ;Loop while [0] is non-empty
    moOmoOmoOmoOMoOMoOmOomOomOo            ;    Decrement [4] twice
    MoOMMMmoOMMM                           ;    Increment [1], then copy [1] to [2]
    MOO                                    ;    Loop while [2] is non-empty
        MOomOomOoMOomoOmoO                 ;        Decrement [0] and [2]
    moo                                    ;    End loop now that [2] is empty
    mOomOoMMMmoOmoOmoOMMM                  ;    Navigate to [0], and copy to [3]
    MOO                                    ;    Perform the next steps only if [3] is non-zero
        OOOmoOMOoMOomOomOomOoMoOMMMmoOMMM  ;        Clear [3], increment [4] twice, increment [1], and copy it to [2]
        MOO                                ;        Loop while [2] is non-empty
            MOomOomOoMoOmoOmoO             ;            Decrement [2] and increment [0]
        moo                                ;        End loop now that [2] is empty
    moO                                    ;        Navigate back to [3]
    moo                                    ;    End the condition
    mOomOomOo                              ;    Navigate back to [0]
moo                                        ;End loop once [0] is empty.
moO                                        ;Navigate to [1]. If [1] is 0, then input was 0.  Otherwise, [4] contains (sign of [0] + 1)
MOO                                        ;Perform the next steps only if [1] is non-zero
    moOmoOmoOMOoMMMOOO                     ;    Navigate to [4], copy it to the register, and clear [4].
moo                                        ;End condition
MMMOOM                                     ;If the register contains something (which is true iff the condition ran), paste it and print it.  Otherwise, no-op and print 0.

I'm still experimenting with golfing it (you will be shocked to discover that golfing in COW is rather difficult), so this may come down a few more bytes in the future.

And there's a 'moo' - language?...

@MukulKumar It's a brainfuck derivative called COW that allows for a couple of things that bf doesn't

Could also call this the "bad mage" language. OUT OF MANA!!!

Hey please take a look at my solution in COW

Cubix, 10 bytes
(W0^I?>O2@

Test it online!
This code is wrapped to the following cube net:
    ( W
    0 ^
I ? > O 2 @ . .
. . . . . . . .
    . .
    . .

The code is then run with the IP (instruction pointer) starting on the I, facing east. I inputs a signed integer from STDIN, pushing it onto the stack.
The next command is ?, which changes the direction of the IP depending on the sign of the top item. If the input is 0, it keeps moving in same direction, running through the following code:

> - Point the IP to the east. (No-op since we're already going east.)
O - Output the top item as an integer.
2 - Push 2 to the stack. This is practically a no-op, because...
@ - Terminates the program.

If the input is negative, the IP turns left at the ?; because this is a cube, the IP moves onto the 0 in the second row, heading east. 0 pushes a literal 0, then this code is run:

^ - Point the IP north.
W - "Sidestep" the IP one spot to the left.
( - Decrement the top item.

The TOS is now -1, and the IP wraps around the cube through a bunch of no-ops . until it hits the >. This runs the same output code mentioned above, outputting -1.
If the input is positive, the same thing happens as with negative inputs, with one exception: the IP turns right instead of left at the ?, and wraps around the cube to the 2, which pushes a literal 2. This is then decremented to 1 and sent to output.

The animation of program flow is very nice!

Nice language. Could it be shorter? 4 flow controls seems much. In operation-count it can be 8 bytes by introducing another ?, but now it uses the bottom half of the cube: ..1nI?..>O@.........?

Six is possible if we ignore outputs after the first: /I?nO1 By the way, this only works because I returns -1 in the online interpreter instead of 0 according to the spec.

@BlackShift Thanks for your interest! I like your suggestions, but I'm not sure how to improve them. It's definitely possible to use less instructions; the tricky part is using less of the cube... ;-) And thanks for pointing out that -1 bug, I'll get that fixed soon.

@ETHproductions IMO It's not a bug, it makes sense for I to return -1 when input ends just like lowercase i does.

^.n.I:?,O@ is quite a simple solution which is also 10 bytes, but perhaps more golfable.

@FlipTack Good idea. I don't immediately see any way to golf that, but I'll keep it in mind...

APL (Dyalog APL), 1 byte
Works for complex numbers too, returning 1∠θ:
×

TryAPL online!

Without that built-in, for integers (as per OP):
¯1⌈1⌊⊢

¯1⌈ the largest of negative one and
1⌊ the smallest of one and
⊢ the argument
TryAPL online!
... and a general one:
>∘0-<∘0

>∘0 more-than-zero
- minus
<∘0 less-than-zero
TryAPL online!

You actually did it in ONE byte... You sir, are a legend. I'm sure Jon Skeet would be proud.

@Mango You are joking, right? There are a handful of single-byte answers to this challenge.

I was being sarcastic, also I said that because this is the first single byte answer I saw.

Wait, is it legal? Can I develop my own language that will contain any function in 1 byte when I will codegolfing?

@Mouvre Yes, but if you don't limit yourself to 256 functions, you'll need to use more than a single byte per character. And there are way more than 256 code golf tasks…

I love absolutely everything about this answer :)

JavaScript (ES6), 9 bytes
Math.sign

Straightforward.
The shortest non-builtin is 13 bytes:
n=>n>0|-(n<0)

Thanks to @Neil, this can be golfed by a byte, but at the cost of only working on 32-bit integers:
n=>n>0|n>>31

Or you could do
n=>n>0?1:!n-1

which seems more golfable, but I'm not sure how.

Non-builtin in 12 bytes for 32-bit signed integer n: n=>n>>31|!!n.

@Neil n>>31 is really smart, thanks!

I don't think the third solution is valid, since Javascript uses double-precision floats for numerics. But, I could be wrong.

@Mego You are correct. I've clarified this in the post.

@ETHproductions My point was, I don't know of any JS implementation that actually uses 32-bit integers rather than double-precision floats for everything. Bit-shifting like that doesn't work with double-precision floats.

@Mego Sorry, I missed your comment. When using bitwise operators, JS implicitly casts their operands to signed 32-bit integers, so the third solution works, but only on numbers from -2147483648 to 2147483647.

Vim, 22 bytes
xVp:s/-/-1^M:s/[1-9]/1^M

Saved one byte thanks to @DJMcMayhem!
Here, ^M is a literal newline.
As @nmjcman101 pointed out in the comments, a single regex can be used (:s/\v(-)=[^0].*/\11^M, 20 bytes) instead, but since this is basically the same as a Retina answer would be, I'm sticking to my own method.
Explanation:
xVp                        Delete everything except the first character. If the number is negative, this leaves a -, a positive leaves any number between 1 and 9, and 0 leaves 0.
   :s/-/-1^M               Replace a - with a -1
            :s/[1-9]/1^M   Replace any number between 1 and 9 with 1.

Here's a gif of it running with a negative number (old version):

Here's it running with 0:

Running with positive:

I really like your method, but it's possible in a single regex: :s/\v(-)=[^0].*/\11

Dithered console GIFs...??

This assumes your cursor is over the first character; I assume that's a valid assumption for vim answers, but an extra 0 in front would remove it as a requirement.

><>, 9 8 bytes
Thanks to Sp3000 for saving a byte.
'i$-%n/

There's an unprintable 0x01 before the /.
Try it online!
Explanation
This is a port of my character code-based Labyrinth answer.
'     Push the entire program (except ' itself) onto the stack, which ends
      with [... 1 47].
i     Read the first character of the input.
$-    Subtract the 47.
%     Take the 1 modulo this value.
n     Output the result as an integer.
0x01  Unknown command, terminates the program.

I think that you can just use a legal ; instead of that unprintable 0x01 to terminate the program correctly :)

@EriktheOutgolfer I need the 0x01 to push a 1 anyway.

Oh, it seems I only tested my suggestion with 123. Lesson learned: test with more cases.

///, 52 36 bytes
/a/\/1\/\///2a3a4a5a6a7a8a9a10a11/1/

Ungolfed, explanation:
/2/1/
/3/1/
/4/1/
/5/1/
/6/1/
/7/1/
/8/1/
/9/1/
/10/1/
/11/1/

It's basically a MapReduce implemenatation, i.e. there are two phases:

Replace all occurrences of digits 2-9 by 1, e.g. 1230405 -> 1110101
Reduce pairs of 11 or 10 to 1 repeatedly, e.g. 1110101-> 1

If there was a - in front initially, it will remain and the output will be -1. A single 0 is never replaced, thus resulting in itself.
Update: Save additional 16 bytes by aliasing //1/ with a, thanks to Martin Ender.
Try it online, with test cases

This is extremely clever!

Python 2, 17 bytes
lambda n:cmp(n,0)

Try it online!

Oh you ninja'd me.

Whoops. Sorry...

Too bad you can't do (0).__rcmp__ ...

You can do -(0).__cmp__ though.

@nyuszika7h Not quite. Trying to use it as a function raises a TypeError.

It's a bit surprising that __cmp__ is the one comparison operator that doesn't have a reflexive version. But, it was always unloved, so I guess it's not that surprising.

@Mego By the contract __cmp__ returns an integer and sign(cmp(a,b)) = -sign(cmp(b,a)), so a __rcmp__ method would probably be slower than just negating the result from __cmp__.

@Pietu1998 But there's even __rand__, and & is commutative...

Labyrinth, 10 bytes
?:+:)%:(%!

Try it online!
Explanation
Labyrinth's control flow semantics actually give you a "free" way to determine a number's sign, because the chosen path at a 3-way fork depends on whether the sign is negative, zero or positive. However, I haven't been able to fit a program with junctions into less than 12 bytes so far (although it may be possible).
Instead, here's a closed-form solution, that doesn't require any branches:
Code    Comment             Example -5      Example 0       Example 5
?       Read input.         [-5]            [0]             [5]
:+      Double.             [-10]           [0]             [10]
:)      Copy, increment.    [-10 -9]        [0 1]           [10 11]
%       Modulo.             [-1]            [0]             [10]
:(      Copy, decrement.    [-1 -2]         [0 -1]          [10 9]
%       Modulo.             [-1]            [0]             [1]
!       Print.              []              []              []

The instruction pointer then hits a dead end, turns around and terminates when % now attempts a division by zero.
Doubling the input is necessary to make this work with inputs 1 and -1, otherwise one of the two modulo operations would already attempt a division by zero.

Your code is happy and turns sad :D

@Stefan You can change the order if you prefer. ;)

C, 24 20 19 18 bytes
I abuse two C exploits to golf this down; This is in C (GCC).
f(a){a=a>0?:-!!a;}

Try it online!

Revision History:
1) f(a){return(a>0)-(a<0);} //24 bytes
2) f(a){a=(a>0)-(a<0);} //20 bytes
3) f(a){a=a>0?:-1+!a;} //19 bytes
4) f(a){a=a>0?:-!!a;} //18 bytes

Revision 1: First attempt. Simple logic
Revision 2: Abuses a memory/stack bug in GCC where, as far as I can tell, a non-returning function will return the last set variable in certain cases.
Revision 3: Abuses ternary behavior where undefined result will return conditional result (which is why the true return on my ternary is nil)
Revision 4: Subtract a bool cast (!!) from the ternary conditional substitution for nil referenced in revision 2.

Brain-Flak 74 42 40 Bytes
Saved 2 bytes thanks to 1000000000
{([({}<([()])>)]<>(())){({}())<>}}{}({})

Try it Online!
Explanation:
{                                }       # if 0 do nothing
   (          )                          # push:
    {}<     >                            # the input, after
       (    )                            # pushing:
        [  ]                             # negative:
         ()                              # 1

 (                    )                  # Then push:
  [            ]                         # the negative of the input
                <>                       # on the other stack with:
                   ()                    # a 1
                  (  )                   # pushed under it

                       {        }        # while 1:
                        ({}())           # increment this stack and...
                              <>         # switch stacks

                                 {}      # pop the top (the counter or 0 from input)
                                   (  )  # push:
                                    {}   # the top (this is a no-op, or pushes a 0)

A little friendly competition.

You can save 2 bytes by removing the zero monad around (())

PHP, 16 bytes
Uses the new spaceship operator.
<?=$argv[1]<=>0;

Don't forget to mention that this is a PHP7 answer only. And since you're using <?=, you should use $_GET[n], which doesn't take any more bytes. To use <?=, you need to be inside a webserver (like Apache), and there you won't have access to $argv. You can try to run <?php var_dump($argv); from a PHP file, acessed through Apache, and it will show NULL.

"To use <?=, you need to be inside a webserver (like Apache)," No. The <?= operator works just fine from the command line.

Running php -r '<?=1' I get PHP Parse error:  syntax error, unexpected '<' in Command line code on line 1. But seems to work fine from a file. I guess you are right.

The -r flag is to run a code snippet. This is complete source. Save it to a file and then run php file.php

I figured it out already. I really didn't knew that it worked from a file, using the (implicit) -f parameter.

It might be useful to add this, to run PHP without having to create a file: echo '<?=$argv[1]<=>0;' | php -- <number> (works on Debian 8.6).

TI-Basic, 8 bytes
median({1,Ans,~1

Alternative solutions (feel free to suggest more):
max(~1,min(Ans,1               8  bytes
0:If Ans:Ans/abs(Ans           9  bytes
(Ans>0)-(Ans<0                 10 bytes

What is the ~ supposed to be?

@ConorO'Brien Negative symbol, to differentiate between TI-Basic's subtract symbol. I know that Cemetech SC uses ~ to represent this token as well.

Oh, cool. I had no idea.

@ConorO'Brien Well, now you know. Thanks for asking :)

This is not valid - using Ans as input does not meet the criteria for being a valid default I/O method (it doesn't have twice as many upvotes as downvotes - currently it's at +19/-12).

You realize it's +7 right? Here's a quick tutorial on it - http://stackoverflow.com/a/40001570/2620293

J, 1 byte
*

Try it online (with test cases)!

Perl, 9 bytes
Requires -E at no extra cost.
say<><=>0

Usage
perl -E 'say<><=>0' <<< -9999
-1
perl -E 'say<><=>0' <<< 9999
1
perl -E 'say<><=>0' <<< -0
0

I'm happy with the fish operator!

It doesn't really "require" -E, that's only if you call it from the CLI instead of a file, which is why I guess you said no extra cost.

@nyuszika7h indeed, requires I guess in the way that testing via -e won't work, but -E is accepted as no longer than -e. As per consensus on meta. I hope that helps a little!

Yeah, I was not suggesting requiring any extra cost for that, as it works fine when that script is executed normally from a file.

say doesn't work in a file, either, without a use feature qw(say); or equivalent (e.g. use v5.x for x>=10).

Pushy, 7 bytes
This is probably the strangest-looking program I've ever written...
&?&|/;#

Try it online!
It uses sign(x) = abs(x) / x, but with an explicit sign(0) = 0 to avoid zero division error.
          \ Take implicit input
&?   ;    \ If the input is True (not 0):
  &|      \  Push its absolute value
    /     \  Divide
      #   \ Output TOS (the sign)

This works because x / abs(x) is 1 when x is positive and -1 when x is negative. If the input is 0, the program jumps to the output command.

4 bytes (non-competing)
Because of holidays and having too much time, I've done a complete rewrite of the Pushy interpreter. The above program still works, but because 0 / 0 now default to 0, the following is shorter:
&|/#

Try it online!

I was also thinking about using abs, but had no idea what to do with the 0. Well done!

Ruby, 10 bytes
->x{x<=>0}

Would 0.<=> also work, or can you not reference methods like that in Ruby?

.<=> expects 1 argument, so it would end up being 0.<=> x, which is longer.

@QPaysTaxes you would need 0.method:<=> because method calls in ruby don't use parentheses and 0.<=> would be interpreted as a method call with too few arguments.

C#, 16 15 bytes
Improved solution thanks to Neil
n=>n>0?1:n>>31;

Alternatively, the built-in method is 1 byte longer:
n=>Math.Sign(n);

Full program with test cases:
using System;

public class P
{
    public static void Main()
    {
        Func<int,int> f =
        n=>n>0?1:n>>31;

        // test cases:
        for (int i=-5; i<= 5; i++)
            Console.WriteLine(i + " -> " + f(i));
    }
}

Try n>>31 instead of n<0?-1:0.

It's a bit sad when the builtin isn't even the shortest solution.

Let's say C# is known to be rather verbose...

A) I don't think you need the trailing ; as a lambda is an expression, not a statement. B) would Math.Sign or Math::Sign or something similar be a valid submission? Not sure how C# in particular handles methods. Basically, would x = Math.Sign; be a valid C# statement if x was initialized with the right type?

@Cyoce x = Math.Sign; is a valid statement if the variable/property x is already declared elsewhere with an appropriate type, for example Func<int, int> x;, and if there is a using directive (or namespace declaration) which makes the identifier Math resolve to the class System.Math. Note that Math.Sign is a "method group" which is not considered to possess a type in itself (although it is implicitly convertible to a bunch of compatible delegate types), and for that reason, var x = Math.Sign; will not work (the strong type for var cannot be inferred).

MATL, 6 bytes
0>EGg-

Input may be a number or an array. The result is number or an array with the corresponding values.
Try it online! Or test several cases using array input.
Explanation
This avoids using the builtin sign function (ZS).
0>   % Take input implicitly. Push 1 if positive, 0 otherwise
E    % Multiply by 2
Gg   % Push input converted to logical: 1 if nonzero, 0 otherwise
-    % Subtract. Implicitly display

MATL is longer than Matlab and Octave?!

He could also have used the built-in ZS as it says in the answer.

Stack Cats, 6 + 4 = 10 bytes
_[:I!:

+4 bytes for the  -nm flags. n is for numeric I/O, and since Stack Cats requires programs to be palindromic, m implicitly mirrors the source code to give the original source
_[:I!:!I:]_

Try it online! As with basically all good Stack Cats golfs, this was found by brute force, beat any manual attempts by a long shot, and can't easily be incorporated into a larger program.
Add a D flag if you'd like to see a step-by-step program trace, i.e. run with -nmD and check STDERR/debug.

Stack Cats uses a tape of stacks which are implicitly filled with zeroes at the bottom. At the start of the program, all input is pushed onto the input stack, with a -1 at the base to separate the input from the implicit zeroes. At the end of the program, the current stack is output, except a base -1 if present.
The relevant commands here are:
_           Perform subtraction [... y x] -> [... y y-x], where x is top of stack
[           Move left one stack, taking top of stack with you
]           Move right one stack, taking top of stack with you
:           Swap top two of stack
I           Perform [ if top is negative, ] if positive or don't move if zero. Then
                negate the top of stack.
!           Bitwise negate top of stack (n -> -n-1)

Note that all of these commands are invertible, with its inverse being the mirror of the command. This is the premise of Stack Cats — all nontrivial terminating programs are of odd length, since even length programs self-cancel.
We start with
               v
               n
              -1
...  0    0    0    0    0  ...

_ subtracts, making the top -1-n, and [ moves the result left one stack:
           v
       -1-n   -1
...  0    0    0    0    0  ...

: swaps top two and I does nothing, since the top of stack is now zero. ! then bitwise negates the top zero into a -1 and : swaps the top two back. ! then bitwise negates the top, turning -1-n back into n again:
          v
          n
         -1   -1
...  0    0    0    0    0  ...

Now we branch based on I, which is applied to our original n:

If n is negative, we move left one stack and end with -n on an implicit zero. : swaps, putting a zero on top, and ] moves the zero on top of the -1 we just moved off. _ then subtracts, leaving the final stack like [-1 -1], and only one -1 is output since the base -1 is ignored.
If n is zero, we don't move and : swaps, putting -1 on top. ] then moves this left -1 on top of the right -1, and _ subtracts, leaving the final stack like [-1 0], outputting the zero and ignoring the base -1.
If n is positive, we move right one stack and end with -n on a -1. : swaps, putting the -1 on top, and ] moves this -1 right, on top of an implicit zero. _ then subtracts, giving 0 - (-1) = 1 and leaving the final stack like [1], which is output.

Piet, 188 53 46 41 bytes
5bpjhbttttfttatraaearfjearoaearbcatsdcclq

Online interpreter available here.
This piet code does the standard (n>0)-(n<0), as there is no sign checking builtin. In fact, there is no less-than builtin, so a more accurate description of this method would be (n>0)-(0>n).
The text above represents the image. You can generate the image by pasting it into the text box on the interpreter page. For convenience I have provided the image below where the codel size is 31 pixels. The grid is there for readability and is not a part of the program. Also note that this program does not cross any white codels; follow the colored codels around the border of the image to follow the program flow.
Explanation

Instruction    Δ Hue   Δ Lightness   Stack
------------   -----   -----------   --------------------
In (Number)    4       2             n
Duplicate      4       0             n, n
Push [1]       0       1             1, n, n
Duplicate      4       0             1, 1, in, in
Subtract       1       1             0, in, in
Duplicate      4       0             0, 0, in, in
Push [4]       0       1             4, 0, 0, in, in
Push [1]       0       1             1, 4, 0, 0, in, in
Roll           4       1             0, in, in, 0
Greater        3       0             greater, in, 0
Push [3]       0       1             3, greater, in, 0
Push [1]       0       1             1, 3, greater, in, 0
Roll           4       1             in, 0, greater
Greater        3       0             less, greater
Subtract       1       1             sign
Out (Number)   5       1             [Empty]
[Exit]         [N/A]   [N/A]         [Empty]

To reduce the filesize any further, I would need to actually change the program (gasp) instead of just compressing the file as I have been doing. I would like to remove one row which would golf this down to 36. I may also develop my own interpreter which would have a much smaller input format, as actually changing the code to make it smaller is not what code golf is about.
The mods told me that the overall filesize is what counts for Piet code. As the interpreter accepts text as valid input and raw text has a much smaller byte count than any image, text is the obvious choice. I apologize for being cheeky about this but I do not make the rules. The meta discussion about this makes my opinions on the matter clear.
If you think that that goes against the spirit of Piet or would like to discuss this further for any reason, please check out the discussion on meta.

I believe the convention for Piet is to count all codels.

@SuperJedi224 That is not what was decided in the meta post, it looks like number of bytes in the image is what I will be going with.

Jelly, 1 byte
Ṡ

TryItOnline!
The monadic sign atom, Ṡ, does exactly what is specified for an integer input, either as a full program or as a monadic link (function taking one argument).

Actually, 1 byte
s

Try it online!
Another case of exactly what it says on the tin - s is the sign function.
Without the builtin (4 bytes):
;A\+

Try it online!
;A\ divides the absolute value of the input by the input. This results -1 for negative inputs and 1 for positive inputs. Unfortunately, due to Actually's error handling (if something goes wrong, the command is ignored), 0 as input leaves two 0s on the stack. + rectifies this by adding them (which causes an error with anything else, so it's ignored).

Mathematica, 4 bytes
Sign

Exactly what it says on the tin

Save a byte with sgn

WolframAlpha isn't the same as Mathematica; it includes automatic interpretation of ambiguous/natural language input.

So I should submit this a separate answer?

seems reasonable to me...

Octave, 26 24 bytes
f=@(x)real(asin(x))/pi*2

This is my first code-golf Octave answer, any golfing tips are appreciated!
Try it online!
The idea for taking the asin comes from the question where it says output the sign :)
Explanation
Note: dividing the number by pi and multiplying it by 2 is the equivalent of dividing the entire number by pi/2
Case 0:
asin(0) yields 0. Taking the real part of it and dividing it by pi/2 makes no difference to the output.
Case positive:
asin(1) yields pi/2. asin of any number bigger than 1 will give pi/2 + complex number. Taking the real part of it gives pi/2 and dividing it by pi/2 gives 1
Case negative:
asin(-1) yields -pi/2. asin of any number smaller than -1 will give -pi/2 + complex number. Taking the real part of it gives -pi/2 and dividing it by pi/2 gives -1

@LuisMendo N will be an integer I'm lucky it says that in the question :)

Oh, I hadn't read that part :)

Clever!!

You don't need f= if the rest is a valid, non-recursive function expression.

@Cyoce Sorry, but I don't prefer anonymous functions

@KritixiLithos your loss.

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)

Practically the same as this answer: http://codegolf.stackexchange.com/a/103831/41805

@KritixiLithos practically but it's also an entirely different llanguage

How about n//abs(n) for two bytes

@Phlarx that will cause divide by zero error as n (and abs n) can be zero

@Dillanm ah, right. Didn't catch that, obvious in hindsight :P

@Phlarx It would have been possible if Python had a way of negating the divide by zero, a la JavaScript per BookOwl solution above x=>x/Math.abs(x)|0

@Dillanm You can, actually, but it's several bytes longer: n and n//abs(n)

V 14 12 bytes
Thanks @DJMcMayhem for 2 bytes.
Uses a reg-ex to do the substitution.  Kind of fun, because it's not a built-in.  I have a more fun function, but it's not working the way I expected.
Í¨-©½0]/±1

Verify Test Cases
This just translates to :%s/\v(-)=[^0].*/\11 which matches one or more - followed by anything but 0, followed by anything any number of times.  It's replaced with the first match (so either a - or nothing) and a 1.  The regex doesn't match 0, so that stays itself.
The More Fun Way (21 bytes)
é
Àé12|DkJòhé-òó^$/a

TryItOnline
This accepts the input as an argument rather than in the buffer.
é<CR> Insert a new line.
À run the argument as V code.  a - will move the cursor to the previous line, and any number will become the count for the next command
é1 insert (count)1's
2| move to the second column
D delete everything from the second column onwards (leaving only one character)
kJ Join the two lines together.
òhé-ò translates to: "run hé- until breaking".  If the 1 was on the second line, this breaks immediately after the h.  If it was on the first line, it will insert a - before breaking.
ó^$/a This fixes the fact that -1,0,1 will leave a blank, and replaces a blank with the argument register.

I knew I should have read that page better.  It's not actually shorter - I forgot 0, but I was trying to take the number in as an argument and then Àé1.  A positive number gives a string of ones, a negative number SHOULD give a string of ones one row up, and 0 would give nothing.  The negative number bit didn't work with À, but did with d$@"

Ah. Well the reason that doesn't work is because there isn't another row up for it to go onto. If you add é<cr> it'll have two empty lines and then that does work. I'm not sure if you can use that to get a full answer

I did have another line to up to, just didn't explicitly say that in my comment.  What's the -- argument you added?

It means "end of options". Since -6 starts with a flag, docopt (the python library for command line options) thinks it's a command-line flag rather than an argument. Adding -- just signals that it's an argument not an option. Otherwise, it won't run at all because of invalid command line invocation.

R, 25 bytes
'if'(x<-scan(),x/abs(x),0)

Takes the number to STDIN. Then checks if it's zero, if not, returns x/|x| which is either 1 of -1, and outputs 0 if x=0.
This is without using the builtin sign of course.

Using the builtin is of course shorter, but less fun: sign(scan()).

Sorry, shouldve explicitly mentioned avoiding the builtin

21 bytes (4.5 years later…)

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

Challenge accepted.

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

05AB1E, 3 bytes
0.S

Try it online!

Oh wow! (I mean, how did you get it so long?)

@a'_' Well, there wasn't any way of doing it shorter than this.

Don't use the legacy version and you have 2 bytes

2 bytes is possible even on the legacy version

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

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.

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

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.

Could you link to an interpreter?

couldn't you output using halt state here :P

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

I'm a bit surprised that x86 doesn't have a builtin for sign.

Casting a C string to a function pointer? That's nasty.

@QPaysTaxes, that is also an elegant/horrifying way to make lambdas in C qsort(a,sizeof a/4,4,"\x8b\7+\6\xc3");

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?

Minecraft Functions (18w11a, 1.13 snapshots), 131 bytes

Uses a function named a in the minecraft namespace
execute if score @p n matches 0 run say 0
execute if score @p n matches 1.. run say 1
execute if score @p n matches ..-1 run say -1

"Takes input" from a scoreboard objective named n, create it with /scoreboard objectives add n dummy and then set it using /scoreboard players set @p n 8.  Then call the function using /function a

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.

Vyxal, 1 byte
±

Try it Online!
Nothing special, just a built-in, but nobody else had posted it yet, so I figured I might as well.
No built-in, 72 bytes
Thanks to @Bubbler for saving 5 bytes.
ȧ/

Try it Online!
Does |x| / x. In Vyxal, 0 / 0 returns 0 instead of a divide by zero error, so this works.

hey, have you seen this bounty? Because you're eligible for it

Non-trivial 6 bytes ((x>0) - (x<0)) and 4 bytes (max(min(x,1),-1))

2 bytes (x/abs(x)), which happens to not error on 0.

@Bubbler the fact that it doesn't error on division by 0 is intentional. I added that a while ago

K (ngn/k), 4 bytes
0 1'

Try it online!
Uses sortedList' as binary search.

0 1' do a binary lookup on 0 1; if the input is 0, it will match the first index, returning 0; if larger than 0, it'll match to the 1 value at the second index, returning 1. If the input is smaller than 0, it will return -1, indicating that the input is less than each value in the sorted list.

tinylisp, 21 bytes
(q((N)(s(l 0 N)(l N 0

Anonymous function that takes a number and returns a number. Try it online!
Ungolfed/explanation
(load library)     ; Load the library to get ungolfed aliases for builtins
(lambda (N)        ; Anonymous function of one argument
  (sub2            ; Take the difference of
    (less? 0 N)    ; 1 if N is positive, 0 otherwise
    (less? N 0)))  ; 1 if N is negative, 0 otherwise

Piet + ascii-piet, 19 bytes (4×6=24 codels)
tabraF krbtKbks?Tbb

Try Piet online!

(previous record: 40 codels/ascii-piet bytes)
An approach involving a CC+ turned out to be the most space-efficient compared to branchless ones.
inN             [n]
dup 1 ! > !     [n !(n>0)]
CC+             [n]  Switch CC if n is 0 or less (follow upper path)
                     otherwise follow lower path
Upper path:
! 1 -           [(n=0)-1]  0 if n is zero, -1 if negative
Lower path:
1               [n 1]  Simply push 1
outN            Print the top number and halt

Some candidates I tried include:

cost 15 (cost is 1 per command, plus pushed numbers minus 1)

1 ! inN dup 1 !  [0 n n 0]
>                [0 n n>0]
3 1 roll >       [n>0 0>n]
- outN           []  Print (n>0)-(0>n)

cost 16, tries not to use roll and instead uses a weird division trick. -1 / positive is -1, -1 / 0 is division by zero, -1 / -1 is 1, and -1 / -2.. is 0. I use + after / to make -1 / 0 case give -1, and then do %3-1 to map each case to the correct output.

1 2 - inN 1 -  [-1 n-1]
/ +            [x]  x = -1/(n-1) as described above
3 % 1 - outN   Print the correct ouptut

cost 16, uses a > and ! instead of two >s. The formula in this case is (n>0)*2 + (n=0) - 1.

inN dup !          [n n=0]
2 1 roll           [n=0 n]
1 ! >              [n=0 n>0]
dup + + 1 - outN   Calculate and print the result of the formula

+1 for building your own interpreter as well!

Trilangle, 21 bytes
?\<'1(0@'^\.!_@>'0.(#

Try it in the online interpreter!
Unfolds to this:
     ?
    \ <
   ' 1 (
  0 @ ' ^
 \ . ! _ @
> ' 0 . ( #

Conceptually equivalent to this C code:
#include <stdio.h>

int main() {
    int x;
    scanf("%i", &x);

    if (x < 0) {
        puts("-1");
    } else if (x > 0) {
        puts("1");
    } else {
        puts("0");
    }
}

but that really doesn't do justice to how dense the control flow is.

As with every Trilangle program, control flow starts in the north corner heading southeast, on the red path in the image above. It reads the following instructions:

?: Read an integer from stdin and push it to the stack
\: Redirect control flow
<: Branch on sign

If the value read in was negative, control flow continues on the green path:

>: Redirect control flow
'0: Push a 0 to the stack
.: No-op
(: Decrement. Because the push-int instruction can only push a single digit, the easiest way to get -1 is '0( (push 0 and decrement) or '0~ (push 0 and bitwise NOT). Either works here; I chose ( arbitrarily.
#: Skip the next character (the /)
.: Another no-op
!: Print the top of the stack
_: No-op in this direction
@: End program

If the value read in was positive or zero, the IP follows the blue path:

(: Decrement. 0 is now negative and positive values are still non-negative.
^: Branch on sign again

If the value read in was initially positive, it takes the yellow path:

_: Redirect control flow
'1: Push a 1 to the stack
\: No-op in this direction
.: No-op
!: Print the top of the stack
@: End program

If the value read in was initially zero, it follows the magenta path. This does a bit more work than necessary to avoid interfering with the other paths:

'1: Push a 1 to the stack
(: Decrement. Great, we've turned zero into zero.
\: Redirect control flow (moving towards the print statement)
': Oh no, another push instruction? But we already have a zero!
0: Push another zero I guess.
\: Redirect control flow, merging with the green path
.!_@: Same as above.

There are other ways I could achieve the same result, e.g.:
?\<)2(.@'^\.!_@>'0(.#

but that has basically the same control structure, and is still 21 bytes. I'm not certain it's impossible to do shorter, but I wouldn't know how.

GNU sed, 17 15 14 bytes
-2 bytes thanks to zeppelin. -1 byte thanks to manatwork.
/^0/!s/\w\+/1/

Try it online!

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

Median@{#,1,-1} and #~Min~1~Max~-1 if you want some more ideas ;)

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

Can I take you up on this challenge?

Of course! .. :)

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 !

Nice. I was going to post something similar that I wrote several months ago.

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.

... I don't think that the Ungolfed version was really necessary

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!

This is surprisingly readable.

@iamnotmaynard funny right?

Befunge-93 (PyFunge), 12 bytes
~"1"%90p1X.@

Try it online!
Note that the X can be anything (except a new line), as it gets written over during run-time. It's just easier for explanation
Similar to my other Befunge answer, but this time it mods the first character by the ASCII for 1 first, so that a positive first digit will turn into a no-op, leaving the 1 on the top of the stack:
~               Read the first *character* of input - either a digit or "-"
 "1"%           Mod the character by the ASCII value of 1. After this step, the character
                is a '-' for negative numbers, '0' for 0, and small, unprintable
                characters for positive numbers

     90p        Puts the character in the space with the X.
        1       Pushes a 1

         X      3 different options based on the character that was put here:
         -      Negative: Subtract the 1 from the implicit 0 to get -1
         0      Zero:     Push 0
               Positive: A no-op, which leaves the 1 on top

          .     Prints out the top of the stack
           @    Ends the program

Hexagony, 16 bytes
...!/~.?.<.!1@.,

Try it online!
Not much smaller than the previous answer, but strangely elegant in comparison.
Expanded:
   . . .
  ! / ~ .
 ? . < . !
  1 @ . ,
   . . .

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.

Python 3, 26 25 bytes
An interesting way to approach this problem using the irregularity of Python 3 hash function.
lambda x:x/abs(~hash(~x))

Try it online!
Explanation
The big idea is to return x/abs(x). However, this causes division by 0 if x is 0.
hash(i) (where \$i\$ is an integer) returns \$i\$ most of the time, with the exception of hash(-1) returning \$-2\$. Thus ~hash(~x) (where ~ denotes bitwise negation) evaluates to:

If x != 0: ~hash(~x) == ~~x == x
If x == 0: ~hash(~0) == ~hash(-1) == ~(-2) == 1

Thus instead of dividing by abs(x), we divides by abs(~hash(~x)) which can never be 0.
Note: This will not work for large integers (\$\ge2^{61}\$), since hash of long integer is calculated differently.

Python 3, 30 bytes
Just here to share another solution.
lambda x:eval(f'x and {x}**0')

Try it online!
Explanation
lambda x:                      # Lambda function with the variable x
         eval(f'      {x}**0') # Raise x to the power of 0
                x and          # Since 0 ** 0 = 1, we prevent that
                               # by using logical and.

Mornington Crescent, 2060 2054 1246 bytes
The improved solution is here!
Take Northern Line to Bank
Take Circle Line to Bank
Take District Line to Parsons Green
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Bank
Take District Line to Acton Town
Take District Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Holborn
Take Central Line to Holborn
Take Central Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Acton Town
Take District Line to Parsons Green
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Central Line to Holborn
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Holborn
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Leicester Square
Take Northern Line to Leicester Square
Take Northern Line to Mornington Crescent

Try it online!
The algorithm:

Parse an integer out of the string provided as input at Parsons Green.
Take the two's complement of the result of step 1 at Notting Hill Gate.
Compute the value of 1 by dividing the result of step 2 by itself.
Take the two's complement of 1 to get -2.
Take the greater of -2 and the result of 2.
Take the two's complement of the result of step 5.
Parse an integer out of a string that contains no integer at Parsons Green, yielding 0.
Take the two's complement of 0 to get -1.
Take the greater of -1 and the result of step 6.
Output the result. In conclusion, the program clamps the integer between the values of -1 and 1, similarly to other solutions.

Old solution:
Took me the better part of two days to figure it out, but I think I have it. The program does not function correctly if faced with -0 or 03 as inputs, so its preconditions are such that there are no leading zeros in the input and that -0 is invalid as well.
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Bank
Take Circle Line to Bank
Take Circle Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Circle Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Green Park
Take Victoria Line to Green Park
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Bank
Take Circle Line to Victoria
Take District Line to Upminster
Take District Line to Upney
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Cannon Street
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Upminster
Take District Line to Upney
Take District Line to Cannon Street
Take District Line to Upney
Take District Line to Cannon Street
Take District Line to Upney
Take District Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Acton Town
Take District Line to Upney
Take District Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Barking
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Barking
Take District Line to Upminster
Take District Line to Bank
Take Circle Line to Bank
Take Northern Line to Mornington Crescent

Try it online!
The algorithm:

Get the first character of the input, which should be - if negative, 0 if zero, or any other digit 1 through 9 if positive.
Convert to ASCII. Now the program should have 45 if the input was negative, 48 if the input was zero, and an integer between 49 and 57 if the input was positive.
Take the bitwise NOT of the ASCII integer. Now the program should have -46 if the input was negative, -49 if the input was zero, and an integer between -50 and -58 if the input was positive.
Add 49 to the previous integer. Now the program should have 3 if the input was negative, 0 if the input was zero, and an integer between -1 and -9 if the input was positive.
Complete integer division by 3. Now the program should have 1 if the input was negative, 0 if the input was zero, and an integer between -1 and -3 if the input was positive.
Take the maximum function of the previous integer and -1 (taking whichever is larger). Now the program should have 1 if the input was negative, 0 if the input was zero, and -1 if the input was positive.
Take the bitwise NOT of the previous integer. Now the program should have -2 if the input was negative, -1 if the input was zero, and 0 if the input was positive.
Add one to the previous integer. Now the program should have -1 if the input was negative, 0 if the input was zero, and 1 if the input was positive. We are done.

Overall, a very rewarding but tiring experience.
EDIT, -6 bytes: Changed Embankment to the shorter Barking.

Just realized there is a much better algorithm to do this. You can use max, bitwise not, max again, and bitwise not again. Oops... that's work for tomorrow.

Lua, 46 45 38 33 32 26 bytes
load"return-1+2/(0^...+1)"

Try it online!
-6 bytes by using load instead of function, thanks to Jo King
Lua has no sign() built-in, and has a strict type system, so things like (n>0)-(n<0) can't be done concisely – its boolean type can't simply be cast to a numerical type.
This version works properly on all integer values and all floating point values.

If n is negative, 0^n+1 yields the value inf, which then becomes zero when 2 is divided by it. Subtract 1 and this is -1.
If n is zero, 0^n+1 yields 2, becoming 1 when 2 is divided by it. Subtract 1 and this is 0.
If n is positive, 0^n+1 is 1, becoming 2 when 2 is divided by it. Subtract 1 and this is 1.

Other languages identified so far in which this works:

Io - Try it online! - might be optimal; beats the Io answer by 6 bytes
Zsh - Try it online! - ties with roblogic's answer, but returns a floating point -1.
R - Try it online! - beats Robin Ryder's no-builtin answer by 5 bytes, but the builtin beats it by 4 bytes: Try it online!
JavaScript - Try it online!, but ETHproductions's non-builtin answer beats it by 2 bytes, and the builtin beats it by 6 bytes: Try it online!
Octave - Try it online! - ties with Tom Carpenter's no-builtin answer, but the builtin beats this by 10 bytes: Try it online!

Previous 38 byte version – works properly on all integer values, as asked for by this challenge. Fails for floating point inputs greater than \$0\$ and less than or equal to \$0.1\$:
function(n)return n//math.abs(n-.1)end

Try it online! - or 33 bytes with load: Try it online!
Previous 43 byte version – works for all floating point values, but fails for integers with an absolute value greater than \$2^{31.5}\$:
function(n)return n/(n*n+#{[0^n]=0})^.5 end

Try it online! - or 41 bytes with load and no global variable usage: Try it online!
Previous 45 byte version – works for all integers and floating point values:
function(n)return n/math.abs(n+#{[0^n]=0})end

Try it online! - or 42 bytes with load: Try it online!
Previous 46 byte versions:
function(n)return n>0 and 1 or#{[n+1]=0}-1 end
function(n)return n<0 and-1 or 1-#{[n+1]=0}end

The versions ranging to 43 to 46 bytes use a tip I have explained here, which is a basically a workaround for Lua's strong typing. Without that trick it would have been 48-49 bytes:
function(n)return n==0 and 0 or n/math.abs(n)end
function(n)return n~=0 and n/math.abs(n)or 0 end
function(n)return n/math.abs(n+0^math.abs(n))end
function(n)return n>0 and 1 or n<0 and-1 or 0 end
function(n)return n<0 and-1 or n>0 and 1 or 0 end

You can also create a function using load and ... for 26 bytes

Zsh, 19 bytes
<<<$[($1>0)-($1<0)]

Try it Online. A neat trick from someone on stackoverflow.

BRASCA, 8 bytes
,'/-1$%n

Try it online!
Explanation
,            - Reverse the stack to take the first character from input
 '/-         - Subtract it by 47
    1$%      - 1 % that value
       n     - And output it

Alice, 19 13 12 bytes
-6 bytes thanks to Martin Ender
-1 byte thanks to Julian
1i'/-%/ o @

Try it online!

It's normally not necessary to use " to push numbers onto the stack. A simpler way is to push the 4 in Cardinal mode and then append the 7 in Ordinal mode. You can then also save a few bytes by interleaving the two segments in Ordinal mode: https://tio.run/##S8zJTE79/98w00Q/n0tXVSHG3EH//39dQyNjAA (I also push the 1 at the start to avoid the ~ but it doesn't really make a difference for the byte count)

Ah, I somehow didn't see appending numbers in Ordinal while checking the command list. Thanks for the advice!

Down to 12 bytes using '/ to get the value 47 on the stack Try it online!

Risky, built-in, 1 byte
1?

Try it online!
Risky, non-built-in, 3 bytes
_?/[?

Try it online!

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

Haskell, 6 bytes
signum

Just a boring built-in.

Perl 6, 9 bytes
+(*cmp 0)

Try it online!
Explanation:
+(     # turn into a number

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

)

CJam, 1 byte
g

Try it online!
Another built-in, just for the sake of completeness.

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

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

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

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.

awk, 17 bytes
!$0||$0=$0<0?-1:1

Test it:
$ echo 0 | awk '!$0||$0=$0<0?-1:1'
0
$ echo 2 | awk '!$0||$0=$0<0?-1:1'
1
$ echo -2 | awk '!$0||$0=$0<0?-1:1'
-1

A 17-byte alternative, but only works on GNU AWK (gawk): !$0||sub(/\w+/,1)

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.

Welcome to Programming Puzzles & Code Golf! If you replace / with //, you don't need to cast to int.

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.

Right, that returns a float. Nothing wrong with that, I guess.

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

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

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.

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.

@zeppelin From everything I've seen, this is as acceptable as a loose anonymous function.

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.

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

@zeppelin Not really. You still append (yourArgument) to (function (x) { /* code here*/ }) since it's just an anonymous function. But as I said, I'm not sure.

@nyuszika7h The difference is that (function (x) { /* code here*/ }) evaluates to an anonymous function reference, which you can then assign or invoke, Math.signum does not evaluate to anything, it is just a  piece of "Method Invocation Expression", which can not be compiled or evaluated, unless you rewrite it to a fully formed method expression by hand (which is obviously a violation of the rules).

The point of using a pre-existing function as a solution is that, if your solution is function_name, you can do something like f=function_name; f(something) and it will work. That only works with the second form.

None of the solutions seem valid to me. The first for the reasons mentioned above. The second because the output is not 1, -1 or 0 but 1.0, -1.0 or 0.0.

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.

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.

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.

That's basically a duplicate of Jordan's solution (which is 14 bytes).

Oh. Damn. ☹ Should I remove mine then?

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.

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.

Nice First Answer! Welcome to the site.

Is there a reason for the space between the . and _ ? Seems like you could save a byte.

Also, you can move one character into the 2 "#@ #" to make "#@!#" instead of "!#@ #". Nice answer though!

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)

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

You can save 3 bytes by replacing pred with (1-) which allows you to replace (`compare`0) with compare 0.

Triangular, 26 15 bytes
$\:-|0U%<g/l0P<

Formats into this triangle:
     $
    \ :
   - | 0
  U % < g
 / l 0 P <

Try it online!

Old broken version that I understand:
$\:-%0U..g/l0P<

Try it online! Currently nonworking until Dennis pulls; found some interpreter bugs.
Formats into this triangle:
    $
   \ :
  - % 0
 U . . g
/ l 0 P <

How it works: The code, without directionals, is read as $:0gP0lU-%.

$ reads an integer from standard input.
stack: i
: duplicates the top stack value.
stack: i,i
0 pushes 0 to the stack.
stack: i,i,0
g pushes i>0 to the stack and discards both values used (thanks, Luis Mendo).
stack: i,i>0
P pops the top stack value into the register.
stack: i
0 pushes 0 to the stack.
stack: i,0
l pushes i<0 to the stack and discards the values used.
stack: i<0
U pulls the register onto the stack.
stack: i<0,i>0
- computes a postfix subtract.
stack: i<0-i>0
% prints the top stack value as an integer.

Idea thanks to caird.

This fails, by outputting the inverse sign. However, this is correct, and is the same length.

GolfScript, 13 bytes
~.{.abs/}{}if

Try it online!
How it Works
Divide by itself if 0 otherwise do nothing, and leaving a zero on the stack to be printed.

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

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.

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

ArnoldC, 498 bytes
IT'S SHOWTIME
HEY CHRISTMAS TREE n
YOU SET US UP 0
GET YOUR ASS TO MARS n
DO IT NOW
I WANT TO ASK YOU A BUNCH OF QUESTIONS AND I WANT TO HAVE THEM ANSWERED IMMEDIATELY
HEY CHRISTMAS TREE m
YOU SET US UP 0
GET TO THE CHOPPER m
HERE IS MY INVITATION n
GET UP n
GET UP 1
ENOUGH TALK
GET TO THE CHOPPER m
HERE IS MY INVITATION m
GET DOWN 1
I LET HIM GO m
GET DOWN 1
ENOUGH TALK
GET TO THE CHOPPER m
HERE IS MY INVITATION m
GET UP 1
I LET HIM GO m
ENOUGH TALK
TALK TO THE HAND m
YOU HAVE BEEN TERMINATED

Try it online!
Explanation
IT'S SHOWTIME

# n = 0
HEY CHRISTMAS TREE n
YOU SET US UP 0

# n = input
GET YOUR ASS TO MARS n
DO IT NOW
I WANT TO ASK YOU A BUNCH OF QUESTIONS AND I WANT TO HAVE THEM ANSWERED IMMEDIATELY

# m = 0
HEY CHRISTMAS TREE m
YOU SET US UP 0

# m = n + n + 1
GET TO THE CHOPPER m
HERE IS MY INVITATION n
GET UP n
GET UP 1
ENOUGH TALK

# m = ((m - 1) % m) - 1
GET TO THE CHOPPER m
HERE IS MY INVITATION m
GET DOWN 1
I LET HIM GO m
GET DOWN 1
ENOUGH TALK

# m = (m + 1) % m
GET TO THE CHOPPER m
HERE IS MY INVITATION m
GET UP 1
I LET HIM GO m
ENOUGH TALK

# print m
TALK TO THE HAND m

YOU HAVE BEEN TERMINATED

Sorry, skynet got my computer before I could read the explanation.

J, 2 bytes
%|

Explanation
It's a hook, so I'll explain it as y%(|y).
  (|y) NB. Magnitude of y.
y%     NB. y/abs(y)

Oh, yes, I am learning J. I want to golf in android and building my own golfing language is hard, so I started learning J.

Does it handle 0?

Yes. In J, division by zero results in +- infinity or 0: https://code.jsoftware.com/wiki/Vocabulary/percent#dyadic (sorry, I don't know how to put links properly)

asm2bf, 91 bytes
Takes input as a string on the input (i.e. 1234). Assumes no leading zeros.
in_ r1
mov r2,r1
eq_ r2,.0
eq_ r1,.-
jnz r1,%m
jnz r2,%z
out .+
end
@m
out .-
end
@z
out .0

Try it online!

COW, 153 75 bytes
oomMMMmoOMoOmoOMMMMOOmoOOOOMOomOoMoOmOomOoMOOMOomoOmoOMMMOOOmooMMMmoomoOOOM

Try it online!
COW can't compare numbers so N is stored in two cells, (if N is not 0) in turns one will be increased and the other decreased. When eventually one of them reaches 0, the loop will stop.
The sign will be in the next cell.
Detailed Explanation:
[0]: N to be incr   [1] = -1   [2]: N to be decr   [3] = 1

i=>+>=          ;   Read N in [0], set [1] = 1 and copy it to [2]
[               ;       Loop while [2] is non-zero
    >°-<+<<     ;       Set [3] = -1, increase [2] then point to [0]
    [           ;           Loop while [0] is non-zero
        ->>=°   ;           Decrease [0], point to [2] copy in register and set it to 0 (to exit)
    ]           ;
    =           ;       Paste from register to [2]
]               ;   When exiting the poited cell could be [0] or [1], in either case...
>o              ;   ...move one right and it would contain the correct output

moo ]    mOo <    MOo -    OOO °    OOM i
MOO [    moO >    MoO +    MMM =    oom o

I've tried other permutations of memory cells but this seems the best.
Setting [3] (a constant) inside the loop is needed to manage the case N=0.

Stax, 2 bytes
:+

Run and debug it
Stax has a sign builtin.  Kind of boring.  Here's a solution that uses clamp instead
Stax, 4 bytes
U1:c

Run and debug it
U    push -1 to stack
 1   push 1 to stack
  :c clamp input between -1 and 1

Java, 12 bytes
Long::signum

Try it online!
Using Long instead of Integer saves 3 bytes.
Long.signum documentation

BitCycle -U, 8 bytes
?v
/=
>!

Try it here!
Explanation
BitCycle's -U flag represents signed integer inputs as follows:

Positive integer \$N\$: a stream of \$N\$ 1's
Negative integer \$-N\$: 0 followed by a stream of \$N\$ 1's
Zero: 0

So all we need to do is output the leading 0 (if any) and the first 1 (if any), and discard the rest of the 1's.
The switch device (=) is very convenient for this task. The first bit that hits a switch passes straight through, but it also activates the switch in one of two directions: a 0 bit turns the switch into {, which redirects all subsequent bits westward, while a 1 bit turns the switch into }, which redirects all subsequent bits eastward.
In our program, we direct the input from the source ? into the switch =, moving southward. The first bit (either the leading 0 or a 1 if there is no leading 0) goes straight through to the sink ! and is output. Then:

If the first bit was a 1 (positive number), the switch activates as }, which redirects the remaining bits off the playfield.
If the first bit was a 0 (non-positive number), the switch activates as {, which redirects the remaining bits westward into the splitter /. This device sends the first bit that hits it southward, where it is redirected into the sink and output. All subsequent bits that reach the splitter pass through it and off the playfield.

Python 3, 28 24 bytes
-4 bytes thanks to @Manny Queen
lambda n:n and abs(n)//n

Try it online!

Microscript II, 21 bytes
N(s""+K45=("-1"ph)!_)
todo: add an explanation

Japt, 2 bytes
Ug

Test it online!
U is the input number, and g is the sign function on numbers. Output is implicit.

Pyth, 2 bytes
._

herokuapp
Pyth's sign function.

QBIC, 18 8 bytes
:?sgn(a)

This utilizes Qbasic's SGN() function. : gets the input in variable a, ? prints.

Original version, before I learnt that QBasic has a SGN() function:
:~a=b|?a\?a/abs(a)

18 bytes. Explanation
:           Get 'a' from the command line
~a=b        If a == b (and b==0 by default)
|?a         Then print a
\?a/abs(a)  Else, print a / abs(a) --> -2/2 leaves the req. -1, 4/4 = 1

Matlab, 4 bytes
sign

Matlab as well has a builtin for it.

Octave, 4 bytes
As with many others, a built-in:
sign

Please, read the first sentence of this meta post before voting.

WolframAlpha, 3 bytes
Try it online: sgn

Python 2, 57 bytes but no conditionals or comparitors
Just to be different, here's a solution that avoids all those ugly arithmetic functions:
def s(n):
 try:r=len([1][:n])*2-n/n
 except:r=0
 return r

Slicing a non-empty sequence [1][:n] returns [1] when n is positive and [] when negative or zero, so to distinguish these cases, n/n throws a divide by zero error for n=0.

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

Possibly doesn't work for the minimum integer (-1<<63)?

@Neil nope! Should work for all 64 bit integers.

Oh, I see now, you just get -1|1 in that case, which is still -1.

Javascript, 37 bytes
function s(n){return n>0?1:n<0?-1:0}

Sorry, updated!

You could use a lambda: n=>n>0?1:n<0?-1:0

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.

Doing I/O as decimal strings could be fun too.

You could argue that all numbers in BF are positive, so ,>+. is a valid answer.

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

Definitely, but it's funny.

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

@Mego: Okay, I see. I never quite understood that standard loophole.

MarioLANG, 868 bytes
;
=
  [@:
 =======================================================
                                                 ))    <
 ======================================================"
@ ((((++
=======            <
        ==========="
      @ -)+)+)+((([!))+((
      =============#====    (<
                         ===="
                       @ +)-[!)))
                       ======#==      )  <
                                 ========"
                                      >([!)
                                      "==#        ))  <
                               @ -(-)[!+   ==========="
                               =======#:          >(([!!
                                                  "===##
                                         @ +((-))[!-
                                         =========#:

Ungolfed, with comments
;[>
==                                                                                output zero
    [@                                                                                :                                                                      * start
  ==================================================================================================                  memory: [limit|limit_copy|counter_add|counter_sub|arg]
                                                    move pointer back to arg  ))    <
  =================================================================================="===
       increase counter limit
@   ((((++
=================    set counters
                              <
                  ============"     increase counter_add by one
                @ -)+)+)+ ((([! ))+((
                ==============#======
                                        reset limit
                                            (<
                                      ======="
                                    @ +)-   [! )))
                                    =========#====   try subtraction
                                                           )  <
                                                   ==========="
                                                         > ( [! )
                                                         "====#==
                                                 @ -(-) [!               try addition
                                                 ========#                   ))  <
                                                                  ==============="
                                                                           > (( [!  !
                                                                           "=====#==#
                                                                @  +((-)) [!
                                                                ===========#

                                                             output one       output minus one
                                                           +:                -:
                                                          ===               ===

What's going on?
The program maintains 5 memory fields (right to left):

Input value, continuously edited in search of zero
Counter for search in negative direction (subtraction)
Counter for search in positive direction (addition)
Helper to reset search radius (limit)
Current search interval radius (limit, k)

The algorithm keeps on searching for zero in both (+ and -) directions, starting at the input value.
It does k negative and k+1 positive steps on each iteration, then increases k by 2.
Once zero has been found, 1 or -1 is output, depending from which side it was reached.
Detection of zero as input is a special case, handled right at the beginning.
Try it online (commented, ungolfed version)

Java 8, 33, 17, 14 bytes
i->i>0?1:i>>31

Does not rely on any questionable code constructs or fragments. This is a complete functional interface implementation.

You can reduce to (int i)->i<0?-1:i>0?1:0 (or even further to i->i<0?-1:i>0?1:0) which are all accepted solutions here on codegolf (http://codegolf.stackexchange.com/a/16100/16236).

@OlivierGrégoire thanks, for some reason I was not thinking "this is a single expression, so the lambda can be reduced."

It can be reduced to this: i->i>0?1:i>>31 (14 bytes)

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.

Befunge, 11 bytes
&:0`\0\`-.@

Try it online!
This is just the obvious (N > 0) - (0 < N) calculation.
&               Read N from stdin.
 :              Make a duplicate copy.
  0`            Calculate N > 0.
    \           Swap the second copy to the top of the stack.
     0\`        Calculate 0 > N.
        -       Subtract the two comparisons: (N > 0) - (0 < N)
         .@     Output the result and exit.

As Martin Ender pointed out, there's potentially a 2-byte shorter solution, using the same idea as his ><> answer:
1~"/"-%.@

Unfortunately this only works if the result of a modulo operation takes the sign of the divisor, which is not that common in Befunge implementations (in particular the reference interpreter doesn't work this way).
1               Push 1 onto the stack for later use.
 ~              Read a character of input (this will be '-' or an ASCII digit).
  "/"-          Subtract 47.
      %         Take the modulo of the 1 we pushed earlier with this difference.
       .@       Output the result and exit.

If you want to try this out you'll probably need to use one of the Python-based interpreters like PyFunge or Befungee. I suspect Fungi might work too.

I think the arithmetic solution I used for my ><> answer and one of my Labyrinth answers would be 2 bytes shorter.

If you use that approach you can save another byte with Befunge-98 which supports '/ for "/". (Provided any 98 interpreters exist with the correct modulo.)

PowerShell, 22 21 bytes
[math]::sign("$args")

Boring built-in, calls the .NET function that does exactly what it says on the tin. Ho-hum.
Try it online!
-1 byte thanks to Veskah.

For 26 bytes however, we get the classic greater-than less-than equation
param($b)($b-gt0)-($b-lt0)

This, at least, has a little bit of logic and thought put into it. Try it online!

Best yet, though is 44 bytes, where we roll our own solution.
param($b)if("$b".indexof('-')){+!!$b;exit}-1

Here we take input $b, stringify it, take the .IndexOf('-') on it, and use it in an if clause. If the negative sign isn't found, this returns -1, which is truthy in PowerShell, so we turn $b into a Boolean with !, invert the Boolean with another !, cast it as an int with +, leave it on the pipeline, and exit. This turns a positive integer (which is truthy) into $false, then $true, then 1, while turning 0 into $true, then $false, then 0. Otherwise, the .IndexOf returned 0 (meaning it was the first character in the string), which is falsey, so we skip the if and just place a -1 on the pipeline. In either case, output via implicit Write-Output happens at program completion. Try it online!

"$args" saves a byte

@Veskah I'm reasonably sure I wrote this answer before I knew that trick, hehe. :D

SAS Macro Language, 43 bytes
In the extremely wordy language...
%macro s(n);%put(%sysfunc(sign(&n)));%mend;

Jellyfish, 3 or 6 bytes
3 bytes with built-in:
p*i

Print (p) the sign (*) of the input (i).
Automatically threads over lists.
6 bytes without built-ins:
p%S
 +i

Print (p) the division (%) of the input (i, taken from south with S) by the absolute value (+) of the input.
Conveniently, division by 0 yields 0 in Jellyfish.
This version also threads over lists.
Try it online!

Clojure, 23 bytes
#(condp > % 0 -1 1 0 1)

This condp macro expands to "if less than 0 return -1, if less than 1 return 0 else 1".
(macroexpand '(condp > % 0 -1 1 0 1))
(let* [pred__7749 > expr__7750 %] (if (pred__7749 0 expr__7750) -1 (if (pred__7749 1 expr__7750) 0 1)))

PHP, 39 38 bytes
no comparison operators
<?=($n=$argv[1])&PHP_INT_MIN?-1:1-!$n;

should work on most systems.
PHP_INT_MIN has only one bit set: the most significant one. If this is set in the input, it is negative.
!$n (cast to integer by the subtraction) evaluates to 0 for positive values and 1 for 0.
lame solution, 30 bytes
<?=($n=$argv[1])?abs($n)/$n:0;

works also on floats.

Python 3, 13 bytes
n//abs(n-.1)

Welcome to the site, and nice first answer! Just so you know, this is only a REPL snippet, which aren't a default valid form of output. You could wrap this in a lambda to make a function submission though. lambda n:n//abs(n-.1)

C, 23 bytes
A more portable (I think) 23-byte solution in C:
f(n){return(n|1)%2-!n;}

C#, 40 bytes
b=>System.Console.Write(b>0?1:b<0?-1:0);

Or with a built-in:
C#, 44 bytes
using System;b=>Console.Write(Math.Sign(b));

Unfortunately it's longer, then the first solution.

MATLAB + Octave, 15bytes
There are a few other Octave/MATLAB answers, but two of the others are simply using a built in, and the other is significantly longer.
The anonymous function:
@(a)(a>0)-(a<0)

Quite simple. If a>0, the answer will be (1-0)=1. If a<0, the answer will be (0-1)=-1. If a==0 the answer will be (0-0)=0.
You can try online here. Simply run the above code and then try with ans(input).

@(a)2/(0^a+1)-1 also works, at the same length of 15 bytes.

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.

8th, 40 3 bytes
With 8th is quite simple to get the sign of N, which is left on TOS
sgn

Testing and Output
ok> 42 sgn .
1
ok> -42 sgn .
-1
ok> 0 sgn .
0

The following code, as an alternative, 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

Japt, 1 byte
g

Try it online!

Scala, 16 bytes
n=>n compareTo 0

Common Lisp, 21 6 bytes
signum

Try it online!

dc, 22 bytes
[pq]sqd0=qdd*vr1-d*v-p

Try it online!
I don't like that 10 bytes of this is eaten up testing for zero, will continue to mull over that. The second half, dd*vr1-d*v-p uses the square root of the square to calculate the absolute value of both our value to test and that value less one. Subtracting the latter from the former yields 1 for a positive value, -1 for a negative.

Aceto, 4 bytes
riyp

ri reads input as integer
y puts sign on stack
p prints it

Try it online!

dc, 15 bytes
[_1*]sa?dd0>a/p

Try it online!
Explanation
This (ab)uses the fact that dc keeps the stack as is, if you're trying to divide by 0 which really helps for this challenge:
[_1*]sa          # store the macro in register a (macro negates the top)
       ?         # push input to stack
        d        # duplicate top
         d0>a    # if top is negative, execute macro
             /   # divides top two values
              p  # print the top of the stack

Functoid, 30 28 bytes
In functoid there is no support for negative integers since numbers are handled as Church numerals. This solution redefines numbers in a way that supports negative numbers (please refer to the explanation):
<|12K0K$BbB
r<@.1,"-"
)<@.([

Try it online! (Here is an input generator)
Explanation
The definition of negative numbers extends the Church numerals by simply introducing another lambda abstraction that encodes the sign of a number (the first argument, ie. x3). Here is how the numbers -2,-1,0,1,2 would look like in this notation:
Decimal number | extended Church numerals | absolute value as Church numeral
---------------+--------------------------+---------------------------------
            -2 |     λλλ(x3 (x2 (x2 x1))) |                   λλ(x2 (x2 x1))
            -1 |          λλλ(x3 (x2 x1)) |                        λλ(x2 x1)
             0 |                  λλλ(x1) |                           λλ(x1)
             1 |               λλλ(x2 x1) |                        λλ(x2 x1)
             2 |          λλλ(x2 (x2 x1)) |                   λλ(x2 (x2 x1))

Now for the explanation of the above code: The characters < will change the direction to left, this saves us four bytes but makes it more difficult to read.. Here's how the code would look like without doing this:
BbB$K0K21|
 @.1,"-"r<
    @.([)<

The combinator BbB ensures that K0 and K2 get grouped as one expression each, here's the more verbose code:
$(K0)(K2)1|
  @.1,"-"r<
     @.([)<

Okay now it's quite readable: First $ will apply the input so we'll have a sign-extended Church numeral as current expression. Applying K0 (constant 0) will evaluate to KK0 (which will "swallow" the next two arguments) in the case of a negative number, in the case of a non-negative number it simply vanishes. In the case of a positive number we'll have K2 which will swallow the argument 1 and else we'll finally get 1.
Summing up the function $(K0)(K2)1 gives the following numbers (regular Church numerals):
if input < 0:
    return 0
elif input > 0:
    return 2
else:
    return 1

The command | will set the direction down iff the current expression evaluates to 0 and up in the other case.

The second line is thus only relevant if the input was negative and it simply prints -1 and terminates
In the other case (ie. hitting the third line) it applies the current expression to [ which decrements it by 1, prints the expression (as a numeral) and terminates

Disclaimer
It might look like the above extension was done just to make this task easier, however this is not the case. In fact most definitions in the untyped (or rather uni-typed) lambda calculus are made because they simplify a lot of operations that one could be interested (such as Booleans or the Church numerals themselves).
As an example the function abs could be "implemented" by just applying the identity function to such an extended numeral which will get rid of one lambda abstraction (and in case of a negative number, keep the absolute value as is).
If you're interested, here is an article that talks more about this definition which is worth a read.

Yabasic, 16 bytes

Anonymous function that takes input as a number, n, and output to STDOUT
input""n
?sig(n)

Try it online!

Perl 5, 9 + 1 (-p) = 10 bytes
$_=$_<=>0

Try it online!

Pyt, 1 byte
±

Try it online!
Boring built-in answer (padding for body length)

Lua (51 Bytes)
n=tonumber(...) print(n<0 and -1 or n>0 and 1 or 0)

... is the variable that represents arguments in lua, tonumber(...) converts the first argument to a number.
also in lua a and b or c is a structure that returns b if a is truthy or c if a is falsy, you can nest this structure as well

Answers should be either functions or full programs. This doesn't seem to be able to take input. N is also guaranteed to be an integer

Stax, 2 bytes
:+

Run and debug online!
Explanation
Added for completeness. It is a builtin, but all built-ins starting with a colon in Stax is actually a macro defined using other Stax operations.
Internally it is defined as c0>s0<-, which is simply (x>0)-(x<0).

SHELL  ( 20 Bytes )
sed s/[1-9][0-9]*/1/

tests:
echo "789" | sed s/[1-9][0-9]*/1/
1

echo "-789" | sed s/[1-9][0-9]*/1/
-1

echo "0" | sed s/[1-9][0-9]*/1/
0

Swift, 44 bytes
func s(i:Int)->Int{return i>0 ?1:i<0 ? -1:0}

Strange spacing around the ternary options, I know, but this was the shortest way.
Try it online!

Brain-Flueue, 40 bytes
{([({})]){({}())<>([{}()()])<>}}(<>[]{})

Try it online!
Readable version
{
 ([({})])
 {
  ({}())<>
  ([{}()()])<>
 }
}
(<>[]{})

MachineCode, 26 bytes
31c085ff0f9fc0c1ef1f29f8c3

Requires the i flag for integer output. Input must be appended to the code on a separate line. This is equivalent to the C code (n>0)-(n<0). Try it online!
Alternatives with the same bytecount:

31c085ff0f95c0c1ff1f09f8c3 - Try it online! Equivalent to the highest voted C submission.
89f8c1ff1ff7d8c1e81f01f8c3 - Try it online! Equivalent to this C code.

Canvas, 3 2 bytes
⤢÷

Try it here!
This might be the shortest solution without a builtin that does the problem for you (I'm looking at you, Jelly.)
Explanation:
⤢÷ | *Full code*
 ÷ | Divide
   | The input (implicit)
⤢  | By its absolute value

Canvas doesn't interpret 0/0 as 0, it actually errors & removes the 2 items without pushing anything (though I'm about to change that as 0 makes much more sense than nothing). The reason that 0 is outputted is that the stack contains an infinite amount of the inputs. And because of that you can actually remove the ：  for 2 bytes

Gol><>, 8 bytes
I:SA:?,h

Try it online!
How it works
I:SA:?,h
I         Input as number; [n]
 :        Duplicate; [n n]
  SA      Absolute value; [n abs(n)]
    :     Duplicate again; [n abs(n) abs(n)]
     ?    Pop one; if it is zero, skip next command
      ,   Nonzero n: Divide n by abs(n)
       h  Print top as number and exit

Gol><>, 11 bytes
I:0(qm$0)+h

Try it online!
How it works
I:0(qm$0)+h

I            Input as number
 :           Duplicate top
  0(         Change top to "top < 0"
    q        If top is true...
     m$      Push -1 and swap top two; the stack is [-1 x]
             Otherwise, skip two commands (m$); the stack is [x]
       0)    Change top to "top > 0"
         +   Add top two
          h  Print top as number and halt

How about I:0)$0(-h for 9 bytes

F#, 140 bytes
open Checked
let s n=
 if n=0 then 0
 else
  try
   let mutable p=n
   while p<>0 do
    p<-p+1
   -1
  with| :? System.OverflowException->1

Try it online!
Basically, if the number is non-zero, keep adding 1 to it until you get either 0 (so the original value was negative) or an overflow (so the original value was positive).
That's all right, isn't it?

naz, 64 bytes
9a5m2x1v3a2x2v1x1f1o0m1a1o0x1x2f1o0x1x3f1r3x1v1e3x2v2e0m1a1o0x3f

Explanation (with 0x commands removed)
9a5m2x1v                 # Set variable 1 equal to 45 ("-")
3a2x2v                   # Set variable 2 equal to 48 ("0")
1x1f1o0m1a1o             # Function 1
                         # Output once, set the register equal to 1, and output again
1x2f1o                   # Function 2
                         # Output once
1x3f                     # Function 3
    1r                   # Read a byte of input
      3x1v1e             # Jump to function 1 if the register equals variable 1
            3x2v2e       # Jump to function 2 if the register equals variable 2
                  0m1a1o # Otherwise, set the register equal to 1 and output
3f                       # Call function 3

Keg, -hr, 13 bytes
:0<[0;|0>[1|0

Try it online!
A very simple switch like comparison happening here.

05AB1E, 2 bytes
A signum built-in.
.±

Try it online!

Scratch 3.0, 9 blocks/44 bytes
For those who are tired of the old way of introducing these answers [I'm looking at you a'_' ...(ಠ ͟ʖಠ)], I'll put the ScratchBlocks Syntax first:
define f(n
set[r v]to(<(n)>(0)>-<(n)<(0
say(r

I decided to use a function instead of the old when gf clicked approach because that means I don't have to deal with having an ask() and wait next.
Try it not online but on Scratch

Always remember to abuse the bool type conversion!

Io, 28 bytes
Does a conditional checking over x/abs(x).
method(x,if(x!=0,x/x abs,0))

Try it online!

-6 bytes by using 2/(0**x+1)-1: Try it online!

Symja, 29 26 bytes
f(x_):=If(x==0,0,x/Abs(x))

Try It Online!
-3 bytes to due porting the idea behind the Io answer.
Answer History
29 bytes
f(x_):=If(x<0,-1,If(x>0,1,0))

For some reason, my edit history didn't save this old approach.

I'd be interested to know what approach you used for the 29 bytes solution

Wait, why is my edit history not showing?

@a'_' I added the 29 byter

Python 3, 25 bytes
lambda x:x and(1,-1)[x<0]

Try it online!
Uses a different approach from other python answers

You could use (x>0)*2-1 instead of (1,-1)[x<0].

dc, 7 bytes
?dd*v/p

Try it online!
Input on stdin, output on stdout.  (There may also be spurious output to stderr, which should be ignored, as usual.)
This uses the formula $$\frac{\left\lfloor\sqrt{n^2}\right\rfloor}n$$
plus the fact that if you divide by 0 in dc, it leaves the 0 at the top of the stack.
(If you try this out, note that negative numbers are written in dc with an initial _ instead of -, since - is only used for the two-argument subtraction operation.)

Desmos, 12 bytes
f(x)=sign(x)

or
$$f\left(x\right)=\operatorname{sign}\left(x\right)$$
Try It On Desmos!

I would change "TIO" to something like "View the plot on desmos.com" not to cause confusion with tio.run.

-1 Byte with sgn nstead of sign

Haskell, 6 bytes
signum

It's a function belonging to the Num typeclass, so every number works.

Python - 23 bytes
print((n>0)*2+(n==0)-1)

This checks if n is greater than 0 (in which case it outputs 2 for the next step), then if it is equal to 0 (in which case it outputs 1) and then subtracts 1, leaving us with -1 if n < 0, 0 if n == 0, and 1 otherwise.
(Yes, the double brackets are necessary, I have checked.)

Pxem, Contents: 0 bytes + Filename: 33 25 bytes

Filename(unprintables are escaped): 1._.c.w\001.r.yXX-.a.p.d.a.n
Content is empty.

Try it online!
Usage
Give an integer from STDIN. The result is output from stdout, with no LF termination.
How it works
XX.z
# Prepare character 1 at this point
.aXX1.z
# integer input is pushed
.a._XX.z
# duplicate, and is it non-zero?
.a.c.wXX.z
  # then come here
  # also \001.r is an idiom to push zero:
  # actually "n=pop;push(int(random()*n))"
  # where 0<=random()<1
  # because filename cannot have null character
  # don't be afraid of such binary for code golf
  .a\001.rXX.z
  # is input less than zero?
  # DOT-y to DOT-a is:
  # while size<2 OR pop>pop; do something; done
  .a.yXX.z
    # if so, push hyphen so string "-1" is made
    .aXXXX-.z
  .a.aXX.z
  # at this point DOT-y popped two items: zero and input integer
  # so no worry about garbages
  # print the string and exit
  # .p is actually: while !empty; do printf "%c", pop; done
  .a.p.dXX.z
# if input is zero, come here
# .n is printf "%d", pop
# OBTW the "1" will on stack, but it's not matter,
# because it is ignored when program ends
.a.a.n

Previously

33bytes of filename: ._.c.w.c00.-.-.z-1.p.d.a1.o.d.a.n

this language is really cool

R, 21 bytes, no builtin
x=scan();x/abs(x^!!x)

Try it online!
Takis input from STDIN. Avoids the builtin sign. This comes out 4 bytes shorter than JAD's solution with if. We cannot use directly x/abs(x) since we would divide by 0 when x=0.
After coercion to integer, !!x will be equal to 1  for all input except 0 (when it is equal to 0). Since 0^0=1, this trick allows to avoid dividing by 0:

For nonzero input, it is equivalent to x/abs(x^1), giving +1 or -1
For x=0, it is equivalent to x/1, giving 0

-5 bytes by using 2/(0^x+1)-1: Try it online!

@Deadcode Nice! That's significantly different; you should post it as a separate answer.

Python 3.8, 47 bytes
print(1if(n:=int(input()))>0else-1if n<0else 0)

tinylisp, 32 bytes
(d F(q((X)(i X(i(l X 0)(q -1)1)0

Try it online!
Since there are no negative number literals in tinylisp, they have to be passed in using subtraction.

Not so--there are negative numbers, just not negative-number literals. (s 0 1) gives -1, for instance.

A0A0, 18 bytes
I0L0V0O0
G-1G-1G-1

Explanation:
I0 L0 V0 O0
I0          ; Reads number as input, stored in the operand
   L0       ; Compare the operand against 0
      V0    ; The operand, value is placed in the next instruction
         O0 ; Ouputs the number of the operand

Thunno, 2 bytes
za

Attempt This Online!
Built-in. Works on lists.
Thunno D, 3 bytes
ZA,

Attempt This Online!
Does \$ x \div |x| \$, which gives \$0\$ for \$0\$.

Binary-encoded Golfical, 17 bytes
The binary-encoded version of Golfical can be converted back to the original image using the Encoder utility included in the github repository, or run directly by using the -x flag
Hexdump of binary encoding:
00 40 03 15 14 14 23 17 14 26 02 01
17 1c 00 01 17

Original program image:

Image magnified 50x with RGB colors labelled:

I'd probably save a few bytes here if the language had an absolute value function (or a native sign function)

Arturo, 14 bytes
$=>[compare&0]

Try it

Regex (Generic), 4 bytes
-?x?

Try it online! - GNU ERE
Try it online! - ECMAScript
Takes its input in unary, as an optional - sign followed by a string of x characters, the count of which represents the absolute value of the number. As such, it is not bijective unary, as zero can be represented in two ways. The regex works with both; it will return - from an input of - (effectively \$-0\$ from an input of \$-0\$), but since \$-0=0\$, this seems acceptable.
Regex (Generic), 2 bytes
.?

Try it online! - GNU ERE
Try it online! - ECMAScript
Takes its input in bijective signed unary. A nonnegative number is a string of x characters, and a nonpositive number is a string of o characters. The the length of the string is the absolute value of the number.

Desmoslang, 8 Bytes
\sgn(IOT

That feeling when Stack doesn't accept your answer because it's too golfed.

Thunno 2, 1 byte
ʂ

Attempt This Online! Built-in.

floor, 39 bytes
f:n->floor(n/(n*n+1))-floor(-n/(n*n+1))
takes an integer \$n\$ as input and computes \$ \left \lfloor \frac{n}{n^2+1} \right \rfloor - \left \lfloor -\frac{n}{n^2+1} \right \rfloor \$
Explanation
floor only supports basic arithmetic operators and the floor-function.
This function exploits the behavior that the floor function returns -1 if \$x\in (-1,0)\$ and 0 if \$x\in[0,1)\$.
To map the input number \$n\$ to the interval \$(-1,1)\$ without changing its sign, it is divided by the positive number \$n^2+1\$ which is guaranteed to have a larger absolute value than \$n\$
Implementation:
To run the program, execute the Python-script with the arguments
-f <source-file> -- <input-number>

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)

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.

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.

Pyke, 5 bytes
0'<>-

Try it here!
0'<>  - 0<input, 0>input
    - - ^-^

BotEngine, 7x17=119
v #  #0123456789
>Ie~>SSSSSSSSSSS
    ^ <<<<<<<<<
 SSSSSSSSS
       >>>>>>>>>^

OCaml, 4 bytes
sign

Didn't even know there was a built-in for this. Alternative 18 bytes solution:
fun x->compare x 0

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.

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.

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.

Math++, 28 bytes
?>a
3+2*!a>$
a/sqrta*a
0>$
0

Could you link to an interpreter?

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

PARI/GP, 4 bytes
sign

Another boring built-in.

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

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

Python 2, 26 Bytes
b=input()
print(b>0)-(b<0)

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 ;

MS Excel, 9 Bytes
Takes Input from cell A1.
=SIGN(A1)

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

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

Ruby, 19 bytes
Not quite as golfy as my other answer.
->n{("%+b"%n)[0,2]}

Outputs -1, +0, +1

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

MY, 3 bytes
Hex:
 1A #Input integer
 2A #Sign function
 27 #Output (trailing newline)

Braingolf, 1 byte
s

Try it online!
Yep.

Common Lisp, 39 bytes
(defun f(x)(if(= x 0)0(if(> x 0)1 -1)))

Try it online!

Implicit, 1 byte
±

Try it online!
After implicits, this program looks like:
$±%
$    read integer input
 ±   push sign
  %  print

T-SQL, 36 bytes
CREATE PROC s @ INT AS PRINT SIGN(@)

Usage:
EXECUTE s -5464

Add++, 9 bytes
L,d0<@0>_

Try it online!
How it works
L,  - Create a lambda.
           Example argument: -8
  d - Duplicate;    STACK = [-8 -8]
  0 - Push 0;       STACK = [-8 -8 0]
  < - Less than;    STACK = [-8  0]
  @ - Reverse;      STACK = [ 0 -8]
  0 - Push 0;       STACK = [ 0 -8 0]
  > - Greater than; STACK = [ 0  1]
  _ - Subtract;     STACK = [-1]
      Implicitly return      -1

Husk, 1 byte
±

Try it online!

REXX, 16 bytes
say sign(arg(1))

Deorst, 11 bytes
i:l0<@l0>@-

Try it online!
Boring (n>0)-(n<0) solution

x86_64 machine code - 26 24 bytes
This is callable function, input in r8 output in rax.
-3 bytes using cbw instruction is 2 bytes instead of movzx rax, al is 4 bytes.
0000000000400080 <output_the_sign>:
  400080:   48 31 c0                xor    rax,rax
  400083:   4d 85 c0                test   r8,r8
  400086:   74 11                   je     400099 <output_the_sign.done>
  400088:   0f 95 c0                setne  al
  40008b:   66 98                   cbw
  40008f:   4c 89 c2                mov    rdx,r8
  400092:   48 c1 fa 1f             sar    rdx,0x1f
  400096:   48 09 d0                or     rax,rdx

0000000000400099 <output_the_sign.done>:
  400099:   c3                      ret

Try it online!

x86, 9 bytes
97    xchg eax, edi
99    cdq
92    xchg eax, edx
39 C2 cmp  edx, eax
7E 01 jng  $+3 ; --,
40    inc  eax ;   |
C3    ret      ; <-'

Try it online!
No one posted this

Vyxal, 1 byte
±

Try it Online!

There's an identical answer from Aaron Miller on this question.

GNU AWK, 15 bytes
sub(/\w+/,!!$0)

Try it online!
The efforts in golfing James Brown's code brought me to this answer. It is exclusive to GNU AWK, due to the use of \w.
AWK, 16 bytes
!$0||$0=/-/?-1:1

Try it online!
This works in traditional AWK.

'$0=_!!$0-2*/-/' this should work for 14 bytes for any awk by skipping the function call, the logical OR ("||"), and the ternary, and using a forced string concat to handle the cases when it's zero

actually it would be $_=_!!$_-2*/-/ for gawk :::::::::::::::: $0=_!!$_-2*/-/ for mawk ::::::::::::::::::: $0=_!!$0-2*(/-/) for nawk :::::::::::::::::::::::: ::::::::::::::: :::::::::::::::: :::::::::::: :::::: :::::::::: 16 bytes for nawk, 14 bytes for any other awk.

also works if the string concat is appended instead of pre-pended ::::::::::::::::::: :::::::::::::::::::::: ::::::::::::: $_=!!$_-2*/-/_

oh turns out one could even skip the negation by switching it to a less than (<) comparison - ::::: same 14 bytes, but doesn't need any hard-coded numbers anymore :::::::::::::::: : $_=(_<$_)-/-/_ . It never ceases to amaze me that this is actually posix-compliant code

Julia, 4 bytes
sign

Try it online!
trivial built-in but it was missing here
Julia (without sign)
round∘tanh 12 bytes
x->tanh(99x) 12 bytes
x->tanh(9x) 11 bytes (input must be Float32)

COBOL (GNU), 68 bytes
S.
SET O TO 0
IF X > 0
SET O TO 1
ELSE IF X < 0
SET O TO -1
END-IF.

Try it online!

Swift, 23 bytes
let s={($0+0).signum()}

There is absolutely nothing interesting about this.

awk
jot 11 -5 |

gawk 'func __(_){return(-_<_)-(_<-_)}'

-5 -1
-4 -1
-3 -1
-2 -1
-1 -1
0 0
1 1
2 1
3 1
4 1
5 1