Usando OR bit a bit 0 per pavimentare un numero

Un mio collega ha imbattuto in un metodo per mettere in piano numeri float usando un bit per bit o:

var a = 13.6 | 0; //a == 13 

Ne stavamo parlando e ci siamo interrogati su alcune cose.

  • Come funziona? La nostra teoria era che l’utilizzo di un simile operatore trasformasse il numero in un numero intero, rimuovendo così la parte frazionaria
  • Ha qualche vantaggio rispetto a fare Math.floor ? Forse è un po ‘più veloce? (gioco di parole non previsto)
  • Ha degli svantaggi? Forse non funziona in alcuni casi? La chiarezza è ovvia, dato che dovevamo capirlo, e bene, sto scrivendo questa domanda.

Grazie.

Come funziona? La nostra teoria era che l’utilizzo di un simile operatore trasformasse il numero in un numero intero, rimuovendo così la parte frazionaria

Tutte le operazioni bit a bit tranne lo spostamento a destra senza segno, >>> , funzionano sugli interi a 32 bit con segno. Quindi usando le operazioni bit a bit convertirai un float in un intero.

Ha qualche vantaggio rispetto a fare Math.floor? Forse è un po ‘più veloce? (gioco di parole non previsto)

http://jsperf.com/or-vs-floor/2 sembra leggermente più veloce

Ha degli svantaggi? Forse non funziona in alcuni casi? La chiarezza è ovvia, dato che dovevamo capirlo, e bene, sto scrivendo questa domanda.

  • Non passerà a jsLint.
  • Solo numeri interi con segno a 32 bit
  • Comportamento comparativo dispari: Math.floor(NaN) === NaN , while (NaN | 0) === 0

Questo è il troncamento in contrapposizione alla pavimentazione. La risposta di Howard è abbastanza corretta; Ma vorrei aggiungere che Math.floor fa esattamente ciò che si suppone rispetto ai numeri negativi. Matematicamente, questo è ciò che è un pavimento.

Nel caso che hai descritto sopra, il programmatore era più interessato al troncamento o al taglio completo del decimale. Anche se la syntax utilizzata ha oscurato il fatto che sta convertendo il float in un int.

In ECMAScript 6, l’equivalente di |0 è Math.trunc , tipo di I dovrei dire:

Restituisce la parte integrale di un numero rimuovendo qualsiasi cifra frazionaria. Tronca solo il punto e le cifre dietro di esso, indipendentemente dal fatto che l’argomento sia un numero positivo o negativo.

 Math.trunc(13.37) // 13 Math.trunc(42.84) // 42 Math.trunc(0.123) // 0 Math.trunc(-0.123) // -0 Math.trunc("-1.123")// -1 Math.trunc(NaN) // NaN Math.trunc("foo") // NaN Math.trunc() // NaN 

Il tuo primo punto è corretto. Il numero viene convertito in un numero intero e quindi vengono rimosse tutte le cifre decimali. Si noti che Math.floor arrotonda il numero intero successivo a meno infinito e quindi dà un risultato diverso quando viene applicato ai numeri negativi.

  • Le specifiche dicono che è convertito in un numero intero:

    Lascia che lnum sia ToInt32 (lval).

  • Prestazioni: questo è stato testato prima su jsperf .