2013-06-12 2 views
5

Ich möchte das Zeichen einer Zahl in JavaScript entfernen. Hier sind die Testfälle, die ich bereits bei jsperf geprüft (http://jsperf.com/remove-sign-from-number)Schnelle und sichere Möglichkeit, das Zeichen einer gesengten Zahl in JavaScript zu entfernen

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) 

Nach diesen Tests: if(n < 0) n *= -1 scheint eine gute Lösung zu sein.

Kennen Sie einen besseren, sichereren und effizienteren Weg, dies zu tun?

Edit 1: Added Nikhils Math.sqrt Fall, aber sqrt ist in der Regel ziemlich langsam in den meisten Systemen.

Edit 2: Jan's Vorschlag für bitweise Ops kann in einigen Fällen schneller sein, wird aber auch Nachkommastellen entfernen und wird daher für mich nicht funktionieren.

+1

Leistungsmerkmale sind sehr unterschiedlich zwischen den Browsern. Auf SeaMonkey übertrifft 'Math.abs' deutlich alle anderen. Auf Konqueror leuchtet bitweise ('if (n <0) n = ~ n + 1 ') [die' && 'Varianten sind alle schlecht] und' Math.abs' stinkt. Alles in allem scheinen 'if (n <0) n * = -1 'und' if (n <0) n = -n' die sicheren zu sein, die nirgendwohin stinken. Ein Problem bei bitweisen Operatoren besteht darin, dass sie die Zahl in eine 32-Bit-Ganzzahl zwingen. Wenn "n" außerhalb dieses Bereichs liegt, würde der bitweise Weg Müll erzeugen. –

Antwort

0

Sie können auch mit n = Math.sqrt (n^n)

+0

Ich denke du meintest 'Math.sqrt (n * n)'? Ich habe das zu meinen Fällen hinzugefügt, aber es ist viel langsamer als die anderen. – Juve

1

Bit-Operatoren die schnellsten sind, finden Sie the results.

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

Darf ich fragen, warum brauchen Sie das in Javascript? Javascript soll nicht die schnellste Sprache sein. Warum nicht C oder Assembly verwenden? –

+0

Ich implementiere eine kleine Proof-of-Concept-Engine in CoffeeScript und benötige diese Zeichenentfernung für einige interne Berechnungen. Ihre Antwort sieht vielversprechend aus (obwohl ich immer noch bei dem wenn-dann * = -1 bleiben würde), was eine bessere Option für guten Durchschnitt zu sein scheint. Leistung über Browser und besonders für Lesbarkeit. Wenn Sie erklären, was Ihr Code im Detail leistet und wie er korrekte Ergebnisse liefert (Zeichen entfernen und Wert beibehalten), kann ich dies als Antwort akzeptieren. Details sind immer gut, insb. für alle anderen Leser. Nicht jeder weiß, bitwise ops gut, esp. in der Javascript Gemeinschaft. – Juve

+0

Entschuldigung, ich habe gerade einige Werte getestet und Ihre Lösung konvertiert auch die JS-Gleitkommazahlen in "Ints" (Ja, ich weiß, dass JS nur Gleitkommazahlen verwendet). Das wollte ich nicht. Ich muss das Zeichen auch von nicht fixierten Nummern entfernen. :( – Juve

1

Da keine bessere Antwort erschien, werde ich die Ergebnisse in dieser Antwort selbst zusammenfassen.

  1. if(n < 0) n *= -1 ist derzeit die beste Wahl. Es funktioniert auf den meisten Plattformen recht gut und ist sehr gut lesbar. Es behält auch die Dezimalbrüche bei.
  2. Andere Varianten, wie n = Math.abs(n), könnten auf anderen Plattformen schneller sein. Aber der Gewinn ist in der Regel nur ein paar Prozent. Möglicherweise möchten Sie den Browser/die Plattform im Voraus erkennen und plattformabhängigen Code erstellen, der die eine oder andere Variante verwendet. Dies kann Ihnen die beste Leistung auf jeder Plattform bieten, bringt jedoch viel Overhead mit sich.
  3. Seien Sie vorsichtig, wenn Sie bitweise Operatoren betrachten, sie könnten auf manchen Plattformen schneller sein, aber die Semantik Ihres Programms ändern (Dezimalbrüche entfernen). Hier
0

ist eine andere Art und Weise:

n * (n>>31|!!n) (nicht unbedingt der schnellste auf allen Browsern, nur eine andere Art und Weise)

Das wird immer eine positive Zahl geben. Grundsätzlich verschiebt >> alle Bits und behält das Zeichen. Dies wird dann bitweise mit 0 oder 1 verknüpft (wenn stattdessen positiv), was entweder -1, 0 oder 1 ergibt. Das bedeutet, dass das Zeichen mit sich selbst multipliziert wird, was es immer gerade macht.

oder sogar mit einer einfachen ternären Operationen:

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

oder

n = n < 0 ? -n : n

Die zweite scheint in allen Browsern konstant schnell, wie einige andere von dem ursprünglichen jsPerf des OP sind: n > 0 || (n *= -1) und n < 0 && (n = -n), die ebenfalls durchgängig schnell sind.

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

Verwandte Themen