The ceil function is a function that rounds up, rounds down, and rounds down. This article covers the primitive type Number and JavaScript floating-point arithmetic.

Unlike the Math static method, the createRound implementation of these three functions controls the precision of the round with the second precision argument, which, when not passed, is equivalent to calling the static method on Math directly.

createRound

Dynamically generate the corresponding function from the function name of the static method passed in to Math as follows:

/**
 * Creates a function like `round`.
 *
 * @private
 * @param {string} methodName The name of the `Math` method to use when rounding.
 * @returns {Function} Returns the new round function.
 */
function createRound(methodName) {
  // Invoke methods on Math by default
  const func = Math[methodName]
  return (number, precision) = > {
    precision = precision == null ? 0 : (precision >= 0 ? Math.min(precision, 292) : Math.max(precision, -292))
    // Need to round up according to accuracy
    if (precision) {
      // Shift with exponential notation to avoid floating-point issues.
      // See [MDN](https://mdn.io/round#Examples) for more details.
      let pair = `${number}e`.split('e')
      const value = func(`${pair[0]}e+${pair[1] + precision}`)
      pair = `${value}e`.split('e')
      return +`${pair[0]}e${+pair[1] - precision}`
    }
    / / don't need
    return func(number)
  }
}
Copy the code

Where E stands for scientific notation, for example:

  • 1e plus 2 is equal to 1 times 10 times 10, which is 100, which is the same thing as 1e2
  • 100e to the minus 2 is equal to 100 over 10 times 10, which is 1

Without passing in a precision argument, this function equals:

function createRound(methodName) {
  const func = Math[methodName]
  return (number) = > {
    return func(number)
  }
}

Copy the code

Equivalent to calling Math[methodName] directly

So let’s go straight to precision-related logic:

precision = precision == null ? 0 : (precision >= 0 ? Math.min(precision, 292) : Math.max(precision, -292))
Copy the code

Here the maximum and minimum values for precision are agreed upon, i.e., maximum 292, Math.pow(10, 292), minimum -292, Math.pow(10, -292). Precision here is the value after e in subsequent scientific notation

So how do we get 292?

Let’s start with SAFE_INTEGER

In JavaScript, there are two values number. MAX_SAFE_INTEGER and number.min_safe_INTEGER. Greater than math.pow (2, 53) -1 (9007199254740991) and less than -math.pow (2, 53) -1 (-9007199254740991) cannot be displayed correctly. You can log 9007199254740993 in your browser and see what the browser returns

console.log(9007199254740993)
9007199254740992
Copy the code

If you want to represent a Number greater than number. MAX_SAFE_INTEGER, you can use BigInt, such as 9007199254740993n

console.log(9007199254740993n)
9007199254740993n
Copy the code

What are the largest values that can be represented in JavaScript? Number.MAX_VALUE and number.min_value. The values of these two numbers are roughly 1.7976931348623157e+308 and -1.7976931348623157e+308

Now, as you might imagine, the largest number that you can express in JavaScript divided by the safety number that we usually use is 292

console.log(Number.MAX_VALUE/Number.MAX_SAFE_INTEGER)
1.99584030953472 e+292
Copy the code

Let’s move on to the following code

let pair = `${number}e`.split('e')
const value = func(`${pair[0]}e+${pair[1] + precision}`)
pair = `${value}e`.split('e')
return +`${pair[0]}e${+pair[1] - precision}`
Copy the code

If precision is positive, use scientific notation to increase value by 10 to the precision, call the Math function, and then reduce it by 10 to the precision. If it’s negative, it’s the opposite. Here also proposed a solution to THE JS floating point number operation problem, that is, the use of scientific notation.

How does the floating-point problem arise?

Computers use binary, and binary floating-point numbers can’t accurately represent numbers like 0.1, 0.2, or 0.3. Similar to base 10 1/3=0.3333333… The same. It’s not just Javascript that has this problem; many programming languages have this problem. For more information, see:

Is floating point math broken?

What Every Programmer Should Know About Floating-Point Arithmetic

Ceil takes the integral function up

/** * Computes `number` rounded up to `precision`. (Round up: The smallest integer is greater than or equal to a given number.) * The smallest integer can be rounded up by a greater than or equal to a given number@since 3.10.0
 * @category Math
 * @param {number} number The number to round up.
 * @param {number} [precision=0] The precision to round up to.
 * @returns {number} Returns the rounded up number.
 * @example* * ceil (4.006) 5 * * * / / = > ceil (6.004, 2) * / / = > 6.01 * * ceil (6040-2) * * / / / = > 6100
const ceil = createRound('ceil')
Copy the code

Floor takes the whole function down

/**
 * Computes `number` rounded down to `precision`.
 *
 * @since 3.10.0
 * @category Math
 * @param {number} number The number to round down.
 * @param {number} [precision=0] The precision to round down to.
 * @returns {number} Returns the rounded down number.
 * @example* * * floor (4.006) / / = > 4 * * floor (0.046, 2) * / / = > 0.04 * * floor (4060-2) * * / / / = > 4000
const floor = createRound('floor')
Copy the code

Round round

/**
 * Computes `number` rounded to `precision`.
 *
 * @since 3.10.0
 * @category Math
 * @param {number} number The number to round.
 * @param {number} [precision=0] The precision to round to.
 * @returns {number} Returns the rounded number.
 * @example* * * round (4.006) / / = > 4 * * round (4.006, 2) * / / = > 4.01 * * round (4060-2) * * / / / = > 4100
const round = createRound('round')
Copy the code