2013-06-12 8 views
5

Chcę usunąć znak liczby w kodzie JavaScript. Oto przypadki testowe, że już zbadane w jsperf (http://jsperf.com/remove-sign-from-number)Szybki i bezpieczny sposób na usunięcie znaku zapieczętowanej liczby w kodzie 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) 

Według tych badań: if(n < 0) n *= -1 wydaje się być dobrym rozwiązaniem.

Czy znasz jakiś lepszy, oszczędzający i bardziej efektywny sposób na zrobienie tego?

Edit 1: Math.sqrt przypadek Added Nikhil, ale sqrt jest zwykle dość powolny w większości systemów.

Edit 2: wniosek Jana do OPS bitowe może być szybszy w niektórych przypadkach, ale spowoduje również usunięcie cyfr po przecinku, a tym samym nie będzie pracować dla mnie.

+1

Charakterystyki pracy różnią się znacznie między przeglądarkami. W SeaMonkey 'Math.abs' wyraźnie przewyższa wszystkie pozostałe. W Konquerorze, bitowe ('if (n <0) n = ~ n + 1') świeci [wszystkie warianty" && "są złe] i' Math.abs' śmierdzi. Ogólnie rzecz biorąc, "if (n <0) n * = -1" i "if (n <0) n = -n" wydają się być tymi bezpiecznymi, które nigdzie nie śmierdzą. Jednym z problemów z operatorami bitowymi jest to, że wymuszają one liczbę na 32-bitową liczbę całkowitą - jeśli 'n' wypadnie poza ten zakres, bitowa metoda wygenerowałaby śmieci. –

Odpowiedz

0

Można również użyć Math.sqrt n = (n^n)

+0

Chyba miałeś na myśli 'Math.sqrt (n * n)'? Dodałem, że jeden do moich przypadków, ale jest znacznie wolniejszy niż inne. – Juve

1

operatory bitowe są najszybsze, zobacz the results.

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

Czy mogę zapytać, dlaczego potrzebujesz tego w javascript? JavaScript nie powinien być najszybszym językiem. Dlaczego nie użyć C lub Assembly? –

+0

Wprowadzam mały silnik gry typu proof-of-concept w CoffeeScript i potrzebuję tego usuwania znaków dla wewnętrznej matematyki. Twoja odpowiedź wygląda obiecująco (chociaż nadal trzymałbym się tego, jeśli-to * = -1), która wydaje się lepszą opcją dla dobrego avg. wydajność w różnych przeglądarkach i esp. dla czytelności. Jeśli wyjaśnisz szczegółowo, co robi twój kod i jak zapewnia poprawne wyniki (usuń znak i zachowaj wartość), mogę przyjąć to jako odpowiedź. Szczegóły są zawsze dobre, szczególnie. dla wszystkich pozostałych czytelników. Nie wszyscy dobrze znają operacje bitowe, szczególnie. w społeczności Javascript. – Juve

+0

Przepraszam, przetestowałem tylko niektóre wartości, a twoje rozwiązanie konwertuje również zmienne JS na "ints" (tak, wiem, że JS używa tylko float). Nie tego chciałem. Muszę też usunąć znak z liczb nie ustalonych. :( – Juve

1

Ponieważ nie pojawiła się żadna lepsza odpowiedź, osobiście podsumuję wyniki tej odpowiedzi.

  1. if(n < 0) n *= -1 jest obecnie najlepszym wyborem. Działa dość dobrze na większości platform i jest bardzo czytelny. Zachowuje również ułamki dziesiętne.
  2. Inne warianty, na przykład n = Math.abs(n), mogą być szybsze na innych platformach. Ale zysk jest zwykle tylko kilka procent. Możesz rozważyć wykrycie przeglądarki/platformy z góry i budowanie kodu zależnego od platformy, które używa jednego lub drugiego wariantu. Zapewnia to najlepszą wydajność na każdej platformie, ale wprowadza wiele kosztów ogólnych.
  3. Należy zachować ostrożność rozważając operatory bitowe, mogą one być szybsze na niektórych platformach, ale mogą zmienić semantykę programu (usuwanie ułamków dziesiętnych).
0

Oto kolejny sposób:

n * (n>>31|!!n) (niekoniecznie najszybszy na wszystkich przeglądarkach, tylko inny sposób)

To zawsze daje liczbę dodatnią. Zasadniczo >> przesuwa wszystkie bity i utrzymuje znak. To jest bitowe OR'd z 0 lub 1 (jeśli dodatni zamiast tego), tworząc albo -1, 0 albo 1. Oznacza to, że znak mnoży się przez siebie, czyniąc go zawsze równym.

Albo nawet z prostych trójskładnikowych operacji:

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

lub

n = n < 0 ? -n : n

Drugi wydaje się konsekwentnie szybko w różnych przeglądarkach, jak to niektórzy inni z PO oryginalnej jsPerf: n > 0 || (n *= -1) i n < 0 && (n = -n), które również są konsekwentnie szybkie.

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

Powiązane problemy