查看这些评估(节点0.10.33的实际转储)
> parseFloat(2.1e-17) === parseInt(2.1e-17)
false
> parseFloat(2.1e-17 + 2) === parseInt(2.1e-17 + 2)
true
> parseFloat(2.000000000000000000000000000000000009) === parseInt(2.00000000000000000000000000000000000009)
true
如何区分整数和非常接近的小数
JS(或者至少是V8)在进行计算时似乎不关心小于10^-16的数字,即使该语言(引用)使用的64位表示应该处理它。
您的例子很容易解释。首先要注意的是,parseInt()
和parseFloat()
将字符串作为输入。所以,在实际解析之前,输入首先被转换为字符串。
第一个很容易看到:
> parseFloat(2.1e-17) === parseInt(2.1e-17)
false
// look at the result of each side
parseFloat(2.1e-17) == 2.1e-17
parseInt(2.1e-17) == 2
当将字符串"2.1e-17"
解析为整数时,解析将在点处停止,因为这不是有效数字,并返回在此之前找到的所有内容,即2
。
> parseFloat(2.1e-17 + 2) === parseInt(2.1e-17 + 2)
true
// look at the result of each side
parseFloat(2.1e-17 + 2) == 2
parseInt(2.1e-17 + 2) == 2
在这里,将首先评估参数中的公式。由于浮点数学的限制(尾数只有52位,不能表示类似2.000000000000000021
的东西),这将导致只有2
。因此,两个parseX()
函数都得到相同的整数参数,这将导致相同的解析数字。
> parseFloat(2.000000000000000000000000000000000009) === parseInt(2.00000000000000000000000000000000000009)
true
与第二种情况的论点相同。唯一的区别是,这次评估的不是公式,而是JavaScript解析器,它只将数字转换为2
。
综上所述:从JavaScript的角度来看,您的数字是一样的。如果您需要更高的精度,您将不得不使用一些库来实现任意精度。
这是我从ReSharper 中学到的东西
而不是使用之类的表达式
if (2.00001 == 2) {}
尝试
if (Math.abs(2.00001 - 2) < tolerance) {}
其中公差应该是可接受的值,例如.001
所以所有差值小于.001的值都将等于
你真的需要10^-16精度吗?我的意思是,这就是为什么1000米=1公里,只需更改输出单位,就不必使用所有小数