Divisione in interi con resto in JavaScript?

In JavaScript, come ottengo:

  1. l’intero numero di volte in cui un determinato numero entra in un altro?
  2. il promemoria?

Per alcuni numeri y e alcuni divisori x calcolare il quoziente ( quotient ) e il resto ( remainder ) come:

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

Non sono esperto in operatori bit a bit, ma ecco un altro modo per ottenere l’intero numero:

 var num = ~~(a / b); 

Questo funzionerà correttamente anche per i numeri negativi, mentre Math.floor() andrà nella direzione sbagliata.

Anche questo sembra corretto:

 var num = (a / b) >> 0; 

Ho fatto alcuni test di velocità su Firefox.

 -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 

Quanto sopra si basa su 10 milioni di prove per ciascuno.

Conclusione: Usa (a/b>>0) (o (~~(a/b)) o (a/b|0) ) per ottenere un aumento dell’efficienza del 20% circa. Ricorda inoltre che sono tutti incoerenti con Math.floor , quando a/b<0 && a%b!=0 .

ES6 introduce il nuovo metodo Math.trunc . Questo consente di correggere la risposta di @ MarkElliot per farlo funzionare anche con numeri negativi:

 var div = Math.trunc(y/x); var rem = y % x; 

Si noti che i metodi Math hanno il vantaggio sugli operatori bit a bit che funzionano con i numeri superiori a 2 31 .

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

È ansible utilizzare la funzione parseInt per ottenere un risultato troncato.

 parseInt(a/b) 

Per ottenere un resto, usa l’operatore mod:

 a%b 

parseIn alcuni problemi con le stringhe, per evitare l’uso del parametro radix con la base 10

 parseInt("09", 10) 

In alcuni casi la rappresentazione della stringa del numero può essere una notazione scientifica, in questo caso, parseInt produrrà un risultato errato.

 parseInt(100000000000000000000000000000000, 10) // 1e+32 

Questa chiamata produrrà 1 come risultato.

JavaScript calcola correttamente il numero di numeri negativi e il resto dei numeri non interi, seguendo le definizioni matematiche per essi.

FLOOR è definito come “il numero intero più grande più piccolo del parametro”, quindi:

  • numeri positivi: FLOOR (X) = parte intera di X;
  • numeri negativi: FLOOR (X) = parte intera di X meno 1 (perché deve essere PIÙ PICCOLO del parametro, cioè più negativo!)

REMAINDER è definito come “residuo” di una divisione (aritmetica euclidea). Quando il dividendo non è un numero intero, il quoziente di solito non è un numero intero, cioè, non c’è resto, ma se il quoziente è forzato a essere un numero intero (ed è ciò che accade quando qualcuno cerca di ottenere il resto o il modulo di un numero in virgola mobile), ci sarà un “non-integer” non intero, ovviamente.

JavaScript calcola tutto come previsto, quindi il programmatore deve stare attento a porre le domande appropriate (e le persone dovrebbero fare attenzione a rispondere a ciò che viene chiesto!) La prima domanda di Yarin NON era “qual è la divisione intera di X di Y”, ma, invece, “il numero intero di volte che un dato intero entra in un altro”. Per i numeri positivi, la risposta è la stessa per entrambi, ma non per i numeri negativi, perché la divisione intera (dividendo per divisore) sarà -1 più piccola delle volte che un numero (divisore) “entra in” un altro (dividendo). In altre parole, FLOOR restituirà la risposta corretta per una divisione intera di un numero negativo, ma Yarin non l’ha chiesto!

gammax ha risposto correttamente, quel codice funziona come richiesto da Yarin. D’altra parte, Samuel ha torto, non ha fatto matematica, credo, o avrebbe visto che funziona (anche, non ha detto quale era il divisore del suo esempio, ma spero che sia stato 3):

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

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

A proposito, ho testato il codice su Firefox 27.0.1, ha funzionato come previsto, con numeri positivi e negativi e anche con valori non interi, sia per il dividendo che per il divisore. Esempio:

-100.34 / 3.57: GoesInto = -28, Remainder = -0.3800000000000079

Sì, ho notato, c’è un problema di precisione lì, ma non ho avuto il tempo di controllarlo (non so se si tratta di un problema con Firefox, Windows 7 o con FPU della mia CPU). Per la domanda di Yarin, però, che riguarda solo gli interi, il codice della gammax funziona perfettamente.

Math.floor(operation) restituisce il valore arrotondato dell’operazione.

Esempio della prima domanda:

 var x = 5; var y = 10.4; var z = Math.floor(x + y); console.log(z); 

Console:

15

Esempio di 2 a domanda:

 var x = 14; var y = 5; var z = Math.floor(x%y); console.log(x); 

Console:

4

Il commento di Alex Moore-Niemi come risposta:

Per i Rubyists qui da Google alla ricerca di divmod , puoi implementarlo come tale:

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

Risultato:

 // [2, 33] 

Se stai solo dividendo con poteri pari a due, puoi utilizzare operatori bit a bit:

 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]; } 

(Il primo è il quoziente, il secondo il resto)

Il calcolo del numero di pagine può essere fatto in un unico passaggio: Math.ceil (x / y)

È ansible utilizzare ternario per decidere come gestire anche valori interi positivi e negativi.

 var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1 

Se il numero è positivo, tutto va bene. Se il numero è negativo, verrà aggiunto 1 a causa di come Math.floor gestisce i negativi.

Io normalmente uso (a - a % b) / b . Probabilmente non è il più elegante, ma funziona.

Questo troncerà sempre verso zero. Non sono sicuro se è troppo tardi, ma qui va:

 function intdiv(dividend, divisor) { divisor = divisor - divisor % 1; if (divisor == 0) throw new Error("division by zero"); dividend = dividend - dividend % 1; var rem = dividend % divisor; return { remainder: rem, quotient: (dividend - rem) / divisor }; }