二进制之谜,深入理解为什么 0.1 + 0.2 !== 0.3
2023-09-22 00:37:07
前言
大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。今天,我们一起来探讨一个困扰了广大前端工程师的问题:为什么 0.1 + 0.2 !== 0.3?
二进制浮点数的原理
计算机在存储和计算数字时,使用二进制来表示数字。二进制只包含两个数字:0 和 1。与我们熟悉的十进制不同,十进制包含 10 个数字:0、1、2、3、4、5、6、7、8、9。
在二进制中,数字的权重是按 2 的幂递增的。最高位的数字表示 2 的 0 次方,接下来是 2 的 1 次方,以此类推。例如,二进制数字 1011 表示:
1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 1 * 2^0 = 8 + 0 + 2 + 1 = 11
浮点数是用来表示小数的。在二进制中,浮点数由三个部分组成:符号位、指数位和尾数。符号位表示数字是正数还是负数。指数位表示数字的阶码,也就是数字乘以 2 的多少次方。尾数表示数字的小数部分。
0.1 + 0.2 !== 0.3 的原因
现在,我们来看一下为什么 0.1 + 0.2 !== 0.3。
0.1 在二进制中表示为 0.0001100110011001100110011001101...。这是一个无限循环的小数。
0.2 在二进制中表示为 0.001100110011001100110011001101...。这也是一个无限循环的小数。
当计算机将这两个数字相加时,它会将它们的小数部分截断为有限位数。这会导致计算结果出现误差。
如何避免此类问题的发生
为了避免此类问题的发生,我们可以使用十进制来表示浮点数。十进制是一种更加精确的表示浮点数的方式。
在 JavaScript 中,我们可以使用 Number.parseFloat()
函数来将字符串表示的十进制数字转换为浮点数。例如:
const a = Number.parseFloat('0.1');
const b = Number.parseFloat('0.2');
const c = a + b;
console.log(c); // 0.3
使用十进制来表示浮点数可以避免计算误差的问题。但是,在某些情况下,使用二进制来表示浮点数也是必要的。例如,当我们需要存储大量的数据时,使用二进制可以节省存储空间。
结论
0.1 + 0.2 !== 0.3 是一个进制问题。这是因为计算机在存储和计算数字时,使用二进制来表示数字。二进制只包含两个数字:0 和 1。浮点数是用来表示小数的。在二进制中,浮点数由三个部分组成:符号位、指数位和尾数。当计算机将两个二进制浮点数相加时,它会将它们的小数部分截断为有限位数。这会导致计算结果出现误差。为了避免此类问题的发生,我们可以使用十进制来表示浮点数。