Number.sign () в javascript

Интересно, есть ли какие-нибудь нетривиальные способы найти знак числа ( signum function )?
Может быть короче / быстрее / элегантнее решения, чем очевидное

var sign = number > 0 ? 1 : number < 0 ? -1 : 0;

Краткий ответ!

Используйте это, и вы будете в безопасности и быстро (источник: moz )

if (!Math.sign) Math.sign = function(x) { return ((x > 0) - (x < 0)) || +x; };

Вы можете посмотреть на производительность и сравнение типов fiddle

Прошло много времени . Дальнейшее происходит в основном по историческим причинам.


Результаты

На данный момент у нас есть следующие решения:


1. Очевидно и быстро

function sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }

1.1. Модификация из kbec - приведение одного типа меньше, более производительно, короче [самое быстрое]

function sign(x) { return x ? x < 0 ? -1 : 1 : 0; }

предупреждение: знак («0») -> 1


2. Элегантный, короткий, не такой быстрый [самый медленный]

function sign(x) { return x && x / Math.abs(x); }

предупреждение: знак (+ - бесконечность) -> NaN , знак («0») -> NaN

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


3. Искусство ... но очень медленное [самое медленное]

function sign(x) { return (x > 0) - (x < 0); }

4. Использование битового сдвига
быстро, но знак (-Infinity) -> 0

function sign(x) { return (x >> 31) + (x > 0 ? 1 : 0); }

5. Типобезопасный [мегабыстрый]

! Похоже, браузеры (особенно chrome v8) делают некоторые волшебные оптимизации, и это решение оказывается намного более производительным, чем другие, даже чем (1.1), несмотря на то, что оно содержит две дополнительные операции и, по логике, никогда не может быть быстрее.

function sign(x) {
    return typeof x === 'number' ? x ? x < 0 ? -1 : 1 : x === x ? 0 : NaN : NaN;
}

Инструменты

Улучшения приветствуются!


[Offtopic] Принятый ответ

  • Андрей Таранцов - +100 за искусство, но к сожалению, это примерно в 5 раз медленнее, чем очевидный подход

  • Frédéric Hamidi - в каком-то смысле это наиболее одобренный ответ (на момент написания), и это вроде как круто, но это определенно не то, как нужно делать, imho. Кроме того, он неправильно обрабатывает бесконечные числа, которые, как вы знаете, тоже являются числами.

  • kbec - усовершенствование очевидного решения. Не то чтобы революционно, но в совокупности считаю такой подход лучшим. Проголосуйте за него :)

100
задан 17 revs, 2 users 100% 26 October 2019 в 03:51
поделиться

1 ответ

Math.sign не поддерживается на IE 11. Я комбинирую лучший ответ с ответом Math.sign:

Math.sign = Math.sign || function(number){
    var sign = number ? ( (number <0) ? -1 : 1) : 0;
    return sign;
};

Теперь, можно использовать Math.sign непосредственно.

0
ответ дан 24 November 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: