最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

performance - Fast and safe way to remove the sign of a singed number in JavaScript - Stack Overflow

programmeradmin8浏览0评论

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] and Math.abs stinks. All in all, if (n < 0) n *= -1 and if (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 - if n falls outside that range, the bitwise way would produce garbage. – Daniel Fischer Commented Jun 12, 2013 at 13:00
Add a ment  | 

6 Answers 6

Reset to default 7

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

  1. 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.
  2. 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.
  3. 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)

发布评论

评论列表(0)

  1. 暂无评论