Math.trunc vs битовое OR

Старый трюк x | 0 для усечения float до int. Сравнение с Math.trunc(x) — оба сводятся к одному машинному коду в горячем V8, но есть нюансы при non-SMI значениях.

Что измеряли

  • Math.trunc(x) vs x | 0 в горячем цикле на миллион итераций.
  • На SMI-входе после прогрева — одинаково.
  • На больших значениях вне диапазона int32 — |0 ломается, Math.trunc работает.

Когда что использовать

// Если уверен, что в int32 диапазоне — равноценно
const i = Math.trunc(x) | 0;   // оба

// Если значение может быть >2^31 — только trunc
Math.trunc(2 ** 50);   // 1125899906842624
(2 ** 50) | 0;         // 0  ← обрезается до 32 бит

Подводные камни

  • |0 сводит к int32, не к int64.
  • >>0 похоже, но даёт uint32.
  • На NaN/Infinity: NaN | 0 = 0, Math.trunc(NaN) = NaN.
  • Микрооптимизация: в современном V8 разница исчезает после JIT, выбирай по читаемости.

Источники

См. также