嘿👋
自从我使用JavaScript已有一段时间了。昨天,我经历了一个非常奇怪的行为。
同时我真的很困惑和惊讶😕。最初我以为,我发现了一个论点再次诅咒JavaScript。
但是,经过一些研究,我发现这不是错误。这是数学,也是计算机处理数字的方式。
好吧,还有其他一些怪异的东西-
幕后发生了什么?
它背后的简单逻辑是计算机使用以2为基的(二进制)浮点数系统。
让我们用一个非常简单的类比来详细了解它。
我们人类使用10进制(十进制)的数字系统来读取,写入和理解日常生活中的数字。
当有人告诉我们1/10时,我们理解并认为它是0.1,但是对于1/3,我们没有确切的值。它是0.333333…..(永无止境),因此,根据我们的理解,我们将其视为0.3(最近的可能的完整数)。
电脑也是如此。当使用JavaScript时,我们写-
let a = 0.1;
众所周知,计算机以二进制格式存储,因此该数字将转换为二进制,但是每个可能的实数都无法转换为二进制。如我们所见,0.1不可能有确切的二进制表示形式,因此JavaScript会将0.1解释为十进制中最接近的二进制数,即-
0.1000000000000000055511151231257827021181583404541015625
以二进制格式-
0.0001100110011001100110011001100110011001100110011001101
同样地,0.2被解释为-
0.200000000000000011102230246251565404236316680908203125
所以当我们做0.1 + 0.2时
0.1000000000000000055511151231257827021181583404541015625
+
0.200000000000000011102230246251565404236316680908203125
=
0.3000000000000000166533453693773481063544750213623046875
真正有趣的是,即使此输出也被转换为最接近的二进制数,因为JavaScript数字也不能表示此精确结果,并且以十进制表示-
0.3000000000000000444089209850062616169452667236328125
现在,我们需要了解在控制台记录该值时会发生什么。
JavaScript不会记录数字的最后一个小数位。取而代之的是,JavaScript仅注销从其附近的其他JavaScript编号中唯一标识该JavaScript编号所需的最小位数。
因此,例如,我们记录值-
console.log(0.1000000000000000055511151231257827021181583404541015625)
// 0.1
输出为0.1
因此,我们尝试记录0.1 + 0.2的结果,
正如我们已经得出的结论是-
0.3000000000000000444089209850062616169452667236328125
因此,JavaScript注销了最小位数以唯一标识该数字,即-
0.30000000000000004
所以这就是为什么0.1 + 0.2的答案是0.30000000000000004
这里要注意的非常重要的一点是,JavaScript数字数据类型实际上不是数字,它是 IEEE 754双精度(64位)浮点数或“双精度”。
此行为不仅限于JavaScript。也已经用其他语言看到过它。有关更多详细信息 -https://0.30000000000000004.com/
我希望,现在您对有人问为什么0.1 + 0.2不是0.3
时要说的话有了一个清晰的认识