Javascript mewakili Number
sebagai angka mengambang ganda presisi 64-bit .
Math.floor
bekerja dengan ini dalam pikiran.
Operasi bitwise bekerja dalam bilangan bulat bertanda 32bit . Bilangan bulat 32bit yang ditandatangani menggunakan bit pertama sebagai penanda negatif dan 31 bit lainnya adalah angka. Karena itu, angka min dan maks yang diizinkan adalah angka 32bit yang ditandatangani adalah -2.147.483.648 dan 2147483647 (0x7FFFFFFFFFF), masing-masing.
Jadi, ketika Anda melakukannya | 0
, pada dasarnya Anda lakukan & 0xFFFFFFFF
. Ini berarti, angka apa pun yang direpresentasikan sebagai 0x80000000 (2147483648) atau lebih besar akan kembali sebagai angka negatif.
Sebagai contoh:
// 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
Juga. Operasi bitwise jangan "lantai". Mereka memotong , yang sama dengan mengatakan, mereka berkeliling paling dekat 0
. Setelah Anda berputar ke angka negatif, Math.floor
bulatkan ke bawah saat bitwise mulai membulatkan ke atas .
Seperti yang saya katakan sebelumnya, Math.floor
lebih aman karena beroperasi dengan angka mengambang 64bit. Bitwise lebih cepat , ya, tetapi terbatas pada lingkup 32bit yang ditandatangani.
Untuk meringkas:
- Bitwise berfungsi sama jika Anda bekerja dari
0 to 2147483647
.
- Bitwise adalah nomor 1 jika Anda bekerja dari
-2147483647 to 0
.
- Bitwise benar-benar berbeda untuk angka yang kurang dari
-2147483648
dan lebih besar dari 2147483647
.
Jika Anda benar - benar ingin mengubah kinerja dan menggunakan keduanya:
function floor(n) {
if (n >= 0 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
if (n > -0x80000000 && n < 0) {
return (n - 1) & 0xFFFFFFFF;
}
return Math.floor(n);
}
Hanya untuk menambahkan Math.trunc
karya seperti operasi bitwise. Jadi Anda bisa melakukan ini:
function trunc(n) {
if (n > -0x80000000 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
return Math.trunc(n);
}