浮点数舍入规则
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
前言
想必大家对小数的舍入很熟悉毕竟四舍五入是我们在小学就听到的概念。但很遗憾计算机并没有采用这种舍入方式因此有时我们会对它的一些进位产生疑惑本文就为大家解开这个疑惑。
IEEE 规定了 4 种舍入方式先来简单看下它们舍入结果(保留 0 位小数:
方式 | 1.40 | 1.60 | 1.50 | 2.50 | -1.50 |
---|---|---|---|---|---|
向零舍入 | 1 | 1 | 1 | 2 | -1 |
向下舍入( − ∞ -\infty −∞ | 1 | 1 | 1 | 2 | -2 |
向上舍入( + ∞ +\infty +∞ | 2 | 2 | 2 | 3 | -1 |
向偶数舍入(default | 1 | 2 | 2 | 2 | -2 |
上面的前三种舍入方式还比较好理解最后一种似乎有点莫名奇妙。但它又是最重要的舍入方式因为它是 IEEE 标准中默认的浮点数舍入方式下文也将围绕这个方式展开。
10 进制小数
先来简单介绍下前三种方式:
- 向零舍入:在一个数轴上向 0 方向移动找到第一个符合的数
- 相当于把正数向下舍入把负数向上舍入
- 得到值 x ‾ \overline{x} x使得 ∣ x ‾ ∣ ≤ ∣ x ∣ \mid\overline{x}\mid \leq \mid x \mid ∣x∣≤∣x∣
- 向下舍入:在一个数轴上向
−
∞
-\infty
−∞ 方向移动找到第一个符合的数
- 得到值 x − x^- x−使得 x − ≤ x x^- \leq x x−≤x
- 向上舍入:在一个数轴上向
+
∞
+\infty
+∞ 方向移动找到第一个符合的数
- 得到值 x + x^+ x+使得 x ≤ x + x \leq x^+ x≤x+
向偶数舍入:
- 首先要找一个中间值保留 0 位小数中间值为: 0.50 0.50 0.50;保留一位小数中间值为: 0.050 0.050 0.050;以此类推
- 将保留位数以后的值与该中间值比较(比如上面的:0.40、0.60、0.50
- 大于中间值采取向上舍入
- 小于中间值采取向下舍入
- 等于中间值向数轴上最近的偶数舍入
下面来是一组向偶数舍入示例(保留 2 位小数:
原数 | 舍入后 | 情况 |
---|---|---|
7.89 4999 7.89\color{Red}4999 7.894999 | 7.89 7.89 7.89 | 小于中间值 |
7.89 5001 7.89\color{Red}5001 7.895001 | 7.90 7.90 7.90 | 大于中间值 |
7.89 5000 7.89\color{Red}5000 7.895000 | 7.90 7.90 7.90 | 等于中间值 |
7.88 5000 7.88\color{Red}5000 7.885000 | 7.88 7.88 7.88 | 等于中间值 |
为什么要采用向偶数舍入?使用四舍五入不好吗?
这是基于统计学的理由:我们有一组数据需要进行舍入后再计算平均数。假如我们我们将 0.5 直接进位那么我们最后算出的平均值将会大于实际值。而现在一个数整体上有 50% 机率变大有 50% 机率变小就不存在平均值偏大的统计误差了。
2 进制小数
向偶数舍入的方法同样可以用在 2 进制小数上。
我们将最低有效位的值 0 认为是偶数值 1 认为是奇数。
- Even when least significant bit is 0
保留 0 位小数的中间值为: 0.1 0 2 0.10_2 0.102保留 1 位小数的中间值为: 0.01 0 2 0.010_2 0.0102以此类推。
- Half way when bits to right of rounding position = 100.. . 2 100..._2 100...2
下面是一组 2 进制小数向偶数舍入示例(保留 2 位小数:
原数 | 舍入后 | 情况 |
---|---|---|
10.00 011 2 10.00\color{Red}011\color{Black}_2 10.000112 | 10.0 0 2 10.00_2 10.002 | 小于中间值 |
10.00 110 2 10.00\color{Red}110\color{Black}_2 10.001102 | 10.0 1 2 10.01_2 10.012 | 大于中间值 |
10.11 100 2 10.11\color{Red}100\color{Black}_2 10.111002 | 11.0 0 2 11.00_2 11.002 | 等于中间值 |
10.10 100 2 10.10\color{Red}100\color{Black}_2 10.101002 | 10.1 0 2 10.10_2 10.102 | 等于中间值 |