Lodash _.ceil Precision Rules for Rounding Up

The _.ceil method in the Lodash JavaScript library computes a number rounded up to a specified precision. While JavaScript’s native Math.ceil only rounds up to the nearest whole integer, Lodash extends this functionality by accepting an optional precision argument. Depending on whether this precision parameter is omitted, positive, or negative, _.ceil applies distinct mathematical rules to round numbers to the nearest integer, decimal place, or power of ten while handling floating-point arithmetic errors.

The Syntax of _.ceil

The function signature for _.ceil is defined as:

_.ceil(number, [precision=0])

Precision Rules Applied by _.ceil

1. Default Precision (precision = 0)

When the precision parameter is omitted or set to 0, _.ceil behaves identically to standard Math.ceil. It rounds the number up to the next highest integer.

2. Positive Precision (precision > 0)

When a positive integer is passed as the precision, _.ceil rounds up to the specified number of digits to the right of the decimal point (fractional digits).

A precision of n rounds the number up to the nearest multiple of \(10^{-n}\).

3. Negative Precision (precision < 0)

When a negative integer is used, _.ceil rounds up to the specified place to the left of the decimal point, targeting powers of ten (tens, hundreds, thousands, etc.).

A precision of -n rounds the number up to the nearest multiple of \(10^n\).

4. Precision Normalization and Coercion

Lodash coerces the precision argument to an integer using internal integer conversion (toInteger). If a floating-point number is provided as the precision:

If precision is NaN, null, or undefined, it defaults to 0.


Floating-Point Precision Handling

A common issue in standard JavaScript calculations is binary floating-point representation error (for example, 1.005 * 100 = 100.49999999999999).

To avoid the inaccuracies caused by standard multiplication and division scaling, Lodash handles precision internally using exponential notation conversion:

  1. The value is converted into scientific exponential notation (value + 'e' + precision).
  2. Math.ceil is applied to this adjusted value.
  3. The number is converted back by reversing the exponent (value + 'e-' + precision).

This ensures that values on rounding boundaries are not shifted into inaccurate rounding directions by standard IEEE 754 precision limits.