简体   繁体   中英

I hava a very simple question about Math.round() in javascript

code:

 let result; result = 2.4999999999999998; console.log(Math.round(result)); result = 2.4999999999999997; console.log(Math.round(result));

The rounding point isn't 5? (Although I know that numbers in JavaScript always occupy 64 bits of memory. Numbers up to 15 integer digits and 17 decimal digits can be defined and displayed in JavaScript.) why the result in console is:

结果在控制台

I expected the both are: 3

Your input values have more digits of precision than JS floats can hold, so the last digit is being rounded to the nearest binary value. This causes the first one to be read as 2.5 , and Math.round() rounds this to 3.

You can see this by printing the values of result before rounding.

 let result; result = 2.4999999999999998; console.log(result, Math.round(result)); result = 2.4999999999999997; console.log(result, Math.round(result));

That extra 1 at the end of 2.4999999999999998 results in it being too close to 2.5 for JavaScript to recognize a difference.

 const withEight = 2.4999999999999998; console.log(2.4999999999999998 === 2.5)

So Math.round(2.4999999999999998) is the same as Math.round(2.5) .

And, as the specification requires that, when a number is rounded that is exactly between two integers, the higher integer is preferred.

  1. Return the integral Number closest to n, preferring the Number closer to +∞ in the case of a tie.

So 3 is the result.

The surprising behavior is not really related to Math.round() . The rounding happens already at the point of parsing the numeric literal, and you can see it by echoing the numbers directly without any explicit rounding:

> 2.4999999999999998
2.5
> 2.4999999999999997
2.4999999999999996 

So the first number is rounded up and the second down - but not corresponding to the common rules of decimal rounding!

The issue is that the numeric literal is converted to a 64-bit floating point number. This has a precision of 53 binary digits. The input number is therefore rounded to the closest number which can be represented with 53 binary digits.

The binary representation of 2.4999999999999996 is:

10.011111111111111111111111111111111111111111111111111

This is 53 significant binary digits, and the next higher binary number is therefore:

10.1

Which is 2.5 in decimal.

So numbers between 2.4999999999999996 and 2.5 cannot be represented exactly and have to be rounded up or down to fit in the floating-point format.

The result of the Math.round() operation is then straightforward: 2.5 is rounded up to 3 and 2.4999999999999997 is rounded down to 2.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM