javascript angular math - Integer-Division mit Rest in JavaScript?




7 Answers

Für eine Anzahl y und einen Teiler x berechnen Sie den Quotienten ( quotient ) und den Rest ( remainder ) wie remainder :

var quotient = Math.floor(y/x);
var remainder = y % x;
example mod

In JavaScript, wie bekomme ich:

  1. wie oft eine gegebene ganze Zahl in eine andere geht?
  2. der Rest?



Ich habe einige Geschwindigkeitstests mit Firefox durchgeführt.

-100/3             // -33.33..., 0.3663 millisec
Math.floor(-100/3) // -34,       0.5016 millisec
~~(-100/3)         // -33,       0.3619 millisec
(-100/3>>0)        // -33,       0.3632 millisec
(-100/3|0)         // -33,       0.3856 millisec
(-100-(-100%3))/3  // -33,       0.3591 millisec

/* a=-100, b=3 */
a/b                // -33.33..., 0.4863 millisec
Math.floor(a/b)    // -34,       0.6019 millisec
~~(a/b)            // -33,       0.5148 millisec
(a/b>>0)           // -33,       0.5048 millisec
(a/b|0)            // -33,       0.5078 millisec
(a-(a%b))/b        // -33,       0.6649 millisec

Das oben genannte basiert auf jeweils 10 Millionen Versuchen.

Schlussfolgerung: Verwenden Sie (a/b>>0) (oder (~~(a/b)) oder (a/b|0) ), um eine Effizienzsteigerung von etwa 20% zu erreichen. Math.floor , dass sie alle nicht mit Math.floor , wenn a/b<0 && a%b!=0 .




var remainder = x % y;
return (x - remainder) / y;



JavaScript berechnet den Boden der negativen Zahlen und den Rest der nicht ganzzahligen Zahlen nach den mathematischen Definitionen für sie.

FLOOR ist definiert als "die größte ganze Zahl kleiner als der Parameter", also:

  • positive Zahlen: FLOOR (X) = ganzzahliger Teil von X;
  • negative Zahlen: FLOOR (X) = ganzzahliger Teil von X minus 1 (weil kleiner sein muss als der Parameter, also negativer!)

REMAINDER ist definiert als das "Überbleibsel" einer Division (euklidische Arithmetik). Wenn der Dividend keine Ganzzahl ist, ist der Quotient in der Regel auch keine Ganzzahl, dh es gibt keinen Rest, aber wenn der Quotient gezwungen wird, eine ganze Zahl zu sein (und das passiert, wenn jemand versucht, den Rest oder den Modul von a zu erhalten) Fließkommazahl), es wird offensichtlich ein nicht ganzzahliges "übrig bleiben".

JavaScript berechnet alles wie erwartet, also muss der Programmierer vorsichtig sein, die richtigen Fragen zu stellen (und Leute sollten vorsichtig sein, um zu antworten, was gefragt wird!) Yarins erste Frage war NICHT "was ist die ganzzahlige Abteilung von X durch Y", aber, stattdessen "die ganze Zahl, die eine gegebene Ganzzahl in eine andere geht". Für positive Zahlen ist die Antwort für beide gleich, aber nicht für negative Zahlen, weil die Ganzzahldivision (Dividend durch Divisor) -1 kleiner als die Zeiten ist, in denen eine Zahl (Divisor) in eine andere (Dividend) "geht". Mit anderen Worten, FLOOR wird die richtige Antwort für eine ganzzahlige Division einer negativen Zahl zurückgeben, aber Yarin hat das nicht gefragt!

gamma hat richtig geantwortet, dieser Code funktioniert wie von Yarin gefragt. Auf der anderen Seite, Samuel hat Unrecht, er hat nicht die Mathematik gemacht, denke ich, oder er hätte gesehen, dass es funktioniert (auch, er hat nicht gesagt, was der Teiler seines Beispiels war, aber ich hoffe es war 3):

Rest = X% Y = -100% 3 = -1

GoesInto = (X - Rest) / Y = (-100 - -1) / 3 = -99 / 3 = -33

Übrigens, ich habe den Code auf Firefox 27.0.1 getestet, er hat wie erwartet funktioniert, mit positiven und negativen Zahlen und auch mit nicht-ganzzahligen Werten, sowohl für Dividend als auch Divisor. Beispiel:

-100,34 / 3,57: GoesInto = -28, Rest = -0,3800000000000079

Ja, mir ist aufgefallen, dass es dort ein Präzisionsproblem gibt, aber ich hatte keine Zeit, es zu überprüfen (ich weiß nicht, ob es ein Problem mit Firefox, Windows 7 oder mit der FPU meiner CPU ist). Für Yarins Frage, die nur ganze Zahlen beinhaltet, funktioniert der Gamma-Code perfekt.




Alex Moore-Niemis Kommentar als Antwort:

Für Rubyists hier von Google auf der Suche nach divmod können Sie es als solches implementieren:

function divmod(x, y) {
  var div = Math.trunc(x/y);
  var rem = x % y;
  return [div, rem];
}

Ergebnis:

// [2, 33]



Normalerweise verwende ich (a - a % b) / b . Es ist wahrscheinlich nicht das eleganteste, aber es funktioniert.




Wenn Sie nur mit Potenzen von zwei teilen, können Sie bitweise Operatoren verwenden:

export function divideBy2(num) {
  return [num >> 1, num & 1];
}

export function divideBy4(num) {
  return [num >> 2, num & 3];
}

export function divideBy8(num) {
  return [num >> 3, num & 7];
}

(Der erste ist der Quotient, der zweite der Rest)




Related