“0.1 + 0.2 = ?” 这个问题,你要是问小学生,他也许会立马告诉你 0.3。但是在计算机的世界里就没有这么简单了,做为一名程序开发者在你面试时如果有人这样问你,小心陷阱喽!
你可能在哪里见过 “0.1 + 0.2 = 0.30000000000000004” 但是知道这背后真正的原理吗?是只有 JavaScript 中存在吗?带着这些疑问本文将重点梳理这背后的原理及浮点数在计算机中的存储机制。
通过本文你能学到什么?
- 浮点数先修知识,更好的帮你理解本文知识
- IEEE 754 标准是什么?
- 0.1 在 IEEE 754 标准中是如何存储的?
- 0.1 + 0.2 等于多少?
- 只有 JavaScript 中存在吗?
先修知识
以下是一些基础的,可能被你所忽略的知识,了解它很有用,因为这些基础知识在我们的下文讲解中都会应用到,如果你已掌握了它,可以跳过本节。
1. 计算机的内部是如何存储的?一个浮点数 float a = 1 会存储成 1.0 吗?
计算机内部都是采用二进制进行表示,即 0 1 编码组成。在计算机中是没有 1.0 的,它只认 0 1 编码。
2. 1bit 可以存储多少个整数?8bit 可以存储多少个整数?
N 个 bit 可以存储的整数是 2 的 N 次方个。8bit 为 2 的 8 次方()。
3. 了解下科学计数法,下文讲解会用到
在日常生活中遇到一个比较大的数字,例如全国总人口数、每秒光速等,在物理上用这些大数表达很不方便,通常可以采用科学计数法表达。
以下为 10 进制科学计数法表达式,底数为 10 ,其中 1≤|a|<10,n 为整数
例如,0.1 的科学计数法表示为 。(一个数的 -1 次方等于该数的倒数,例如 = )
在 IEEE 754 标准中也类似,只不过它是以一个二进制数来表示,底数为 2,以下为 0.1 的二进制表达式:
4. 十进制小数如何转二进制?
十进制小数转二进制,小数部分,乘 2 取整数,若乘之后的小数部分不为 0,继续乘以 2 直到小数部分为 0 ,将取出的整数正向排序。
例如:0.1 转二进制
0.1 * 2 = 0.2 --------------- 取整数 0,小数 0.2
0.2 * 2 = 0.4 --------------- 取整数 0,小数 0.4
0.4 * 2 = 0.8 --------------- 取整数 0,小数 0.8
0.8 * 2 = 1.6 --------------- 取整数 1,小数 0.6
0.6 * 2 = 1.2 --------------- 取整数 1,小数 0.2
0.2 * 2 = 0.4 --------------- 取整数 0,小数 0.4
0.4 * 2 = 0.8 --------------- 取整数 0,小数 0.8
0.8 * 2 = 1.6 --------------- 取整数 1,小数 0.6
0.6 * 2 = 1.2 --------------- 取整数 1,小数 0.2
...