Javascript rappresenta Number
come doppia precisione numeri mobile a 64 bit .
Math.floor
funziona con questo in mente.
Operazioni bit per bit lavorano in 32 bit firmato interi. Gli interi con segno a 32 bit utilizzano il primo bit come significante negativo e gli altri 31 bit sono il numero. Per questo motivo, il numero minimo e massimo consentito per i numeri con segno a 32 bit sono -2.147.483.648 e 2147483647 (0x7FFFFFFFF), rispettivamente.
Quindi, quando lo fai | 0
, lo stai essenzialmente facendo & 0xFFFFFFFF
. Ciò significa che qualsiasi numero rappresentato come 0x80000000 (2147483648) o superiore restituirà un numero negativo.
Per esempio:
// Safe
(2147483647.5918 & 0xFFFFFFFF) === 2147483647
(2147483647 & 0xFFFFFFFF) === 2147483647
(200.59082098 & 0xFFFFFFFF) === 200
(0X7FFFFFFF & 0xFFFFFFFF) === 0X7FFFFFFF
// Unsafe
(2147483648 & 0xFFFFFFFF) === -2147483648
(-2147483649 & 0xFFFFFFFF) === 2147483647
(0x80000000 & 0xFFFFFFFF) === -2147483648
(3000000000.5 & 0xFFFFFFFF) === -1294967296
Anche. Le operazioni bit a bit non "pavimentano". Essi troncano , che è lo stesso che dire, si completano più vicino 0
. Una volta che si va in giro per i numeri negativi, Math.floor
giri verso il basso mentre bit a bit iniziano arrotondamento in su .
Come ho detto prima, Math.floor
è più sicuro perché funziona con numeri fluttuanti a 64 bit. Bitwise è più veloce , sì, ma limitato a ambito firmato a 32 bit.
Riassumere:
- Bitwise funziona allo stesso modo se lavori da
0 to 2147483647
.
- Bitwise ha 1 numero di sconto se lavori da
-2147483647 to 0
.
- Bitwise è completamente diverso per i numeri minori di
-2147483648
e maggiori di 2147483647
.
Se vuoi davvero modificare le prestazioni e utilizzare entrambi:
function floor(n) {
if (n >= 0 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
if (n > -0x80000000 && n < 0) {
return (n - 1) & 0xFFFFFFFF;
}
return Math.floor(n);
}
Solo per aggiungere Math.trunc
funziona come operazioni bit per bit. Quindi puoi farlo:
function trunc(n) {
if (n > -0x80000000 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
return Math.trunc(n);
}