浮点数与 IEEE 754
文章将从以下几个问题出发,讨论浮点数与 IEEE 754 标准:
- 二进制 0.1,用十进制表示的话是多少?十进制的 0.1,用二进制表示又是多少?
- 为什么 0.1 + 0.2 = 0.30000000000000004?
- 单精度和双精度浮点数的有效小数位分别是多少?
- 单精度浮点数能表示的范围是什么?
- 浮点数为什么会存在 -0?infinity 和 NaN 又是怎么表示的?
小数的二进制和十进制转换
二进制转十进制
和整数转换一样,采用各位数值和位权相乘。记住小数点后第一位是从 -1 开始即可。
十进制转二进制
十进制整数转二进制采用“除 2 取余,逆序排列”法,直到商为0为止。
十进制小数转二进制采用“乘 2 取整,顺序排列”法,直到小数为0或达到精度要求。
这样一来,有些十进制为有限小数转为二进制就成了无限循环小数了,例如:
什么是浮点数
计算机中小数的表示法,其实有定点和浮点两种。
定点数:数的小数点固定在同一位置不变。
因为资源的限制,数学中的小数无法直接在计算机中准确表示,为了更好地表示便有了浮点数。这种表示方法类似于基数为10的科学记数法,是对小数的近似表示。简单来说,浮点数是相对于定点数而言的,小数点位置是浮动的。
维基百科中对浮点数的解释如下:
在计算机科学中,浮点(英语:floating point,缩写为FP)是一种对于实数的近似值数值表现法,由一个有效数字(即尾数)加上幂数来表示,通常是乘以某个基数的整数次指数得到。以这种表示法表示的数值,称为浮点数(floating-point number)。
一个浮点数 a 由两个数 m 和 e 来表示:
选择一个基数 b 和精度 p(即使用多少位来存储)。尾数 m 是形如 d.ddd…ddd 的 p 位数(每一位都为介于0到b-1之间的整数,包括0和b-1)。如果m的第一位是非0整数,m称作正规化的。e是指数。使用一个单独的符号位 s 来表示正负。
即浮点数是指用符号、尾数、基数和指数这四部分来表示的小数。

浮点数的 IEEE 754 表示
解释这个问题之前,先来看一个经典的问题:0.1+0.2=?
人来计算这个问题,答案无疑是 0.3 ;但是让计算机来解决这个问题,答案还是 0.3 吗?
我们来写个程序看一下:
C:
1 |
|
C++:
1 |
|
Java:
1 | public class Main { |
Python:
1 | a = 0.1 |
Go:
1 | import "fmt" |
结果无一例外,结果均为:
1 | 0.30000000000000004 |
这就要回到 IEEE 754 标准关于浮点数的规定。