Wonder if there are any nontrivial ways of finding number\'s sign (signum function)?
May be shorter / faster / more elegant solutions than the obvious one
The methods I know of are as follows:
Math.sign(n)
var s = Math.sign(n)
This is the native function, but is slowest of all because of the overhead of a function call. It does however handle 'NaN' where the others below may just assume 0 (i.e. Math.sign('abc') is NaN).
((n>0) - (n<0))
var s = ((n>0) - (n<0));
In this case only the left or right side can be a 1 based on the sign. This results in either 1-0
(1), 0-1
(-1), or 0-0
(0).
The speed of this one seems neck and neck with the next one below in Chrome.
(n>>31)|(!!n)
var s = (n>>31)|(!!n);
Uses the "Sign-propagating right shift". Basically shifting by 31 drops all bits except the sign. If the sign was set, this results in -1, otherwise it is 0. Right of |
it tests for positive by converting the value to boolean (0 or 1 [BTW: non-numeric strings, like !!'abc'
, become 0 in this case, and not NaN]) then uses a bitwise OR operation to combine the bits.
This seems the best average performance across the browsers (best in Chrome and Firefox at least), but not the fastest in ALL of them. For some reason, the ternary operator is faster in IE.
n?n<0?-1:1:0
var s = n?n<0?-1:1:0;
Fastest in IE for some reason.
jsPerf
Tests performed: https://jsperf.com/get-sign-from-value