我在MDN上看着Number.isInteger()
。我遇到了这个例子-
Number.isInteger(5.000000000000001); // false
我将值更改为5.0000000000000001
,如果我在控制台上执行相同的方法,则结果为:
Number.isInteger(5.0000000000000001); // true
也有5.0000000000000001 === 5
是true
。
有人可以解释一下这里发生了什么吗?
答案 0 :(得分:2)
JavaScript使用IEEE-754基本的64位二进制浮点格式。在这种格式中,每个有限数都表示为整数 M 乘以2的幂,2 E 。 M 的大小必须小于2 53 , E 的范围可能是−1074至971。(更常见的描述标度是 M 和 E 不同,因此 M 具有小数位而不是整数,但这在数学上等效。)
对于数字5.000000000000001,可以精确表示的是使用 E = −50,因为这使 M 尽可能大,约为5• 2 50 = 1.25•2 52 。如果将 E 减小一倍,则 M 大约必须为1.25•2 53 ,超过2 53 限制。
因此,假设 E = −50,我们需要5.000000000000001 = M •2 −50 ,这意味着 M = 5.000000000000001•2 50 = 5•2 50 + .000000000000001•2 50 。显然,第一项5•2 50 是整数。第二项.000000000000001•2 50 约为1.1259。因此,将5.000000000000001转换为JavaScript的Number格式时,我们需要使 M 为整数,因此必须将1.1259舍入为1。结果是 M = 5•2 < sup> 50 + 1,因此数字为(5•2 50 + 1)•2 −50 = 5.000000000000000888178419701970012523233233890533447265625。
另一方面,当我们有5.0000000000000001,又有一个零时,我们有5.0000000000000001•2 50 = 5•2 50 + .0000000000000001•2 50 。在这种情况下,第二项.0000000000000001•2 50 约为.11259。因此,将5.0000000000000001转换为JavaScript的数字格式时,我们必须将.11259舍入为0,因此数字为((5•2 50 )•2 −50 = 5