Javascript представляє Number
як 64-бітні плаваючі числа подвійної точності .
Math.floor
працює з цим на увазі.
Бітові операції працюють в 32 - бітному підписав цілі числа. Цілі числа з 32-бітним підписом використовують перший біт як негативний означувач, а інші 31 біт - це число. Через це мінімальне та максимальне число дозволених 32-бітних підписаних номерів складають -2,147,483,648 та 2147483647 (0x7FFFFFFFF) відповідно.
Отже, коли ти робиш | 0
, ти по суті робиш це & 0xFFFFFFFF
. Це означає, що будь-яке число, представлене як 0x80000000 (2147483648) або більше, повернеться як негативне число.
Наприклад:
// 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
Також. Побітні операції не «перекриваються». Вони усікаються , що це те саме, що й казати, вони кружляють найближче 0
. Після того, як ви йдете навколо негативних чисел Math.floor
раундів вниз в той час як побітовое починають округляти вгору .
Як я вже говорив раніше, Math.floor
це безпечніше, оскільки він працює з 64-бітовими плаваючими номерами. Побітовое швидше , так, але обмежується 32 - бітовим підписали сферу.
Узагальнити:
- Побіт працює так само, якщо ви працюєте з
0 to 2147483647
.
- Побітове значення - 1 число, якщо ви працюєте з
-2147483647 to 0
.
- Побітове значення зовсім інше для чисел, менших
-2147483648
і більших за 2147483647
.
Якщо ви дійсно хочете налаштувати продуктивність, використовуйте обидва:
function floor(n) {
if (n >= 0 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
if (n > -0x80000000 && n < 0) {
return (n - 1) & 0xFFFFFFFF;
}
return Math.floor(n);
}
Просто додати Math.trunc
твори, як бітові операції. Тож ви можете це зробити:
function trunc(n) {
if (n > -0x80000000 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
return Math.trunc(n);
}