2013-06-12 4 views
5

Я хочу удалить знак числа в JavaScript. Вот тестовые случаи, которые я уже исследованные в JSPerf (http://jsperf.com/remove-sign-from-number)Быстрый и экономичный способ удаления знака оного в JavaScript

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) 

Согласно этим тестам: if(n < 0) n *= -1 кажется хорошим решением.

Знаете ли вы, что лучше, сохранить и более эффективный способ сделать это?

Edit 1: Math.sqrt случай Добавлена ​​Нихилу, но sqrt, как правило, довольно медленно и в большинстве систем.

Редакция 2: Предложение Яна для побитовых операций может быть быстрее в некоторых случаях, но также будет удалять дробные цифры и, следовательно, не будет работать для меня.

+1

Эксплуатационные характеристики сильно различаются между браузерами. В SeaMonkey «Math.abs» явно превосходит все остальные. На Konqueror побитовое ('if (n <0) n = ~ n + 1') сияет [все версии' && 'все там плохие] и' Math.abs' воняет. В общем, 'if (n <0) n * = -1' и' if (n <0) n = -n' кажутся безопасными, которые нигде не воняют. Одна из проблем с побитовыми операторами состоит в том, что они заставляют число в 32-битное целое число - если 'n' выходит за пределы этого диапазона, поразрядный способ может вызвать мусор. –

ответ

0

Вы также можете использовать п = Math.sqrt (п^п)

+0

Я предполагаю, что вы имели в виду 'Math.sqrt (n * n)'? Я добавил, что один к моим делам, но он намного медленнее, чем другие. – Juve

1

Битовые операторы являются самыми быстрыми, см the results.

if(n < 0) n = ~n+1; 
+1

Могу ли я спросить, зачем вам это нужно в javascript? Javascript не должен быть самым быстрым языком. Почему бы не использовать C или Assembly? –

+0

Я внедряю небольшой игровой движок с доказательством концепции в CoffeeScript и нуждаюсь в этом удалении знака для некоторой внутренней математики. Ваш ответ выглядит многообещающим (хотя я все равно придерживаюсь if-then * = -1), который, кажется, лучший вариант для хорошего avg. производительность в браузерах и особенно. для удобочитаемости. Если вы объясните, что делает ваш код, и как он дает правильные результаты (удалите знак и сохраните значение), я могу принять его как ответ. Детали всегда хорошие, особенно. для всех остальных читателей. Не все знают побитовые операции хорошо, особенно. в сообществе Javascript. – Juve

+0

Извините, я просто проверил некоторые значения, и ваше решение также конвертирует JS-поплавки в «ints» (да, я знаю, что JS использует только float). Это не то, что я хотел. Мне также нужно удалить знак из нефиксированных чисел. :( – Juve

1

Поскольку лучшего ответа не появилось, я кратко изложу выводы в этом ответе.

  1. if(n < 0) n *= -1 в настоящее время лучший выбор. Он достаточно хорошо работает на большинстве платформ и очень читаем. Он также сохраняет десятичные дроби.
  2. Другие варианты, такие как n = Math.abs(n), могут быть быстрее на других платформах. Но выигрыш обычно составляет лишь несколько процентов. Вы можете рассмотреть возможность обнаружения браузера/платформы и создания платформы, зависящей от платформы, которая использует тот или иной вариант. Это может дать вам лучшую производительность на каждой платформе, но приносит много накладных расходов.
  3. Будьте осторожны при рассмотрении побитовых операторов, они могут быть быстрее на некоторых платформах, но могут изменить семантику вашей программы (удаление десятичных дробей).
0

Вот еще один способ:

n * (n>>31|!!n) (не обязательно самый быстрый на всех браузерах, просто еще один способ)

Это всегда будет давать положительное число. В основном >> сдвигает все биты и сохраняет знак. То есть тогда побитовое OR'd с 0 или 1 (если положительно), создавая либо -1, 0, либо 1. Это означает, что знак умножается сам по себе, делая его всегда ровным.

Или даже с простыми тройными операциями:

n * (n < 0 ? -1 : 1)

или

n = n < 0 ? -n : n

Второй кажется стабильно быстр во всех браузерах, как некоторые другие из оригинального JSPerf Ора в: n > 0 || (n *= -1) и n < 0 && (n = -n), которые также последовательно бывают быстрыми.

JSPerf: https://jsperf.com/remove-sign-from-a-number