How Lodash toInteger Strips Decimals Safely

The _.toInteger method in the Lodash JavaScript library converts values into integers while safely removing decimal components. Unlike native JavaScript shortcuts that rely on 32-bit bitwise operators or functions with unexpected coercion quirks, _.toInteger utilizes a defensive conversion pipeline. It handles floating-point numbers, prevents numeric overflow beyond the 32-bit boundary, sanitizes non-numeric types, and ensures consistent truncation toward zero.

Under the hood, _.toInteger delegates the heavy lifting of normalization to Lodash's internal toFinite method before removing the fractional remainder. The process follows a clear set of steps to guarantee type safety and mathematical precision:

1. Coercion with toFinite

Before any decimal stripping occurs, the input value is passed to toFinite. This step ensures that the value is converted to a valid JavaScript double-precision float:

2. Modulo Subtraction Instead of Bitwise Truncation

In native JavaScript, developers often strip decimals using bitwise operations such as Math.trunc(x), x | 0, or ~~x. However, bitwise operators force values into signed 32-bit integers, which causes severe overflow and unexpected negative numbers for any value larger than 2,147,483,647.

Lodash avoids this limitation by calculating the fractional remainder using the modulo operator:

const remainder = result % 1;
return remainder ? result - remainder : result;

Subtracting the remainder (result % 1) from the number preserves the 64-bit floating-point representation. This allows _.toInteger to safely process values up to Number.MAX_SAFE_INTEGER (\(9,007,199,254,740,991\)) and even clamp larger finite floats without truncation artifacts caused by 32-bit conversion.

3. Truncation Toward Zero

Because result % 1 retains the sign of the original number in JavaScript, subtracting the remainder inherently truncates values toward zero.

For positive numbers like 5.95, the operation 5.95 - (5.95 % 1) yields 5. For negative numbers like -5.95, the operation -5.95 - (-5.95 % 1) yields -5. This avoids the issue seen with Math.floor(), which rounds negative numbers downward away from zero (turning -5.95 into -6).

By combining input sanitization through toFinite with 64-bit modulo subtraction, _.toInteger strips decimal values safely without data corruption, overflow vulnerabilities, or unexpected type coercions.