I want to remove the sign of a Number in JavaScript. Here are the test cases that I already examined at jsperf
if(n < 0) n *= -1;
if(n < 0) n = -n;
n = Math.abs(n)
(n < 0) && (n *= -1)
(n < 0) && (n = -n)
n = Math.sqrt(n*n)
According to these tests: if(n < 0) n *= -1
seems to be a good solution.
Do you know of any better, save, and more efficient way to do that?
Edit 1: Added Nikhil's Math.sqrt
case, but sqrt
is usually quite slow in most systems.
Edit 2: Jan's proposal for bitwise ops may be faster in some cases but will also remove fractional digits, and thus will not work for me.
I want to remove the sign of a Number in JavaScript. Here are the test cases that I already examined at jsperf
if(n < 0) n *= -1;
if(n < 0) n = -n;
n = Math.abs(n)
(n < 0) && (n *= -1)
(n < 0) && (n = -n)
n = Math.sqrt(n*n)
According to these tests: if(n < 0) n *= -1
seems to be a good solution.
Do you know of any better, save, and more efficient way to do that?
Edit 1: Added Nikhil's Math.sqrt
case, but sqrt
is usually quite slow in most systems.
Edit 2: Jan's proposal for bitwise ops may be faster in some cases but will also remove fractional digits, and thus will not work for me.
Share Improve this question edited Sep 15, 2022 at 13:37 mikemaccana 123k110 gold badges427 silver badges531 bronze badges asked Jun 12, 2013 at 9:58 JuveJuve 10.8k14 gold badges68 silver badges94 bronze badges 1-
1
Performance characteristics vary widely between browsers. On SeaMonkey,
Math.abs
clearly outperforms all the others. On Konqueror, bitwise (if (n < 0) n = ~n+1
) shines [the&&
variants are all bad there] andMath.abs
stinks. All in all,if (n < 0) n *= -1
andif (n < 0) n = -n
seem to be the safe ones that don't stink too badly anywhere. One problem with bitwise operators is that they force the number into a 32-bit integer - ifn
falls outside that range, the bitwise way would produce garbage. – Daniel Fischer Commented Jun 12, 2013 at 13:00
6 Answers
Reset to default 7You could use Math.abs()
.
It returns the absolute value of the number
Since no better answer appeared I will summarize the findings in this answer myself.
if(n < 0) n *= -1
Is currently the best choice. It performs reasonably well on most platforms and is very readable. It also preserves the decimal fractions.- Other variants, such as
n = Math.abs(n)
, might be faster on other platforms. But the gain is usually only a few percentages. You may consider detecting the browser/platform upfront and building platform-depended code that uses one or the other variant. This can give you the best performance on each platform but introduces a lot of overhead. - Be careful when considering bitwise operators, they might be faster on some platforms but can change the semantics of your program (removing decimal fractions).
Bitwise operators are the fastest, see the results.
if(n < 0) n = ~n+1;
Here is another way:
n * (n>>31|!!n)
(not necessarily the fastest on all browsers, just another way)
That will always give a positive number. Basically >>
shifts all the bits and keeps the sign. That is then bitwise OR'd with 0 or 1 (if positive instead), producing either -1, 0 , or 1. That means the sign gets multiplied by itself, making it always even.
Or even with a simple ternary operations:
n * (n < 0 ? -1 : 1)
or
n = n < 0 ? -n : n
The second one seems consistently fast across browsers, as is some others from the OP's original jsPerf: n > 0 || (n *= -1)
and n < 0 && (n = -n)
, which are also consistently fast.
jsPerf: https://jsperf./remove-sign-from-a-number
Not sure if this is an XY problem type situation, but zero-fill right-shifting by 0 gets rid of the sign bit. I can't think of a faster way.
1 >>> 0; // 1
-1 >>> 0; // 4294967295
You can also use n=Math.sqrt(n^n)