IEEE-754 中的舍入方法
IEEE-754 中的舍入方法
并非所有实数都可以精确地存储为浮点数。
考虑一个以归一化浮点数形式表示的实数:
x
=
±
1.
b
1
b
2
b
3
.
.
.
b
n
.
.
.
×
2
m
x = \pm 1.b_1 b_2 b_3 ... b_n ... \times 2^m
x=±1.b1b2b3...bn...×2m,其中
n
n
n 是尾数中的位数,
m
m
m 是给定浮点数系统的指数。若
x
x
x 没有精确的浮点数表示,则会用最近的两个浮点数
x
−
x_{-}
x− 或
x
+
x_{+}
x+ 来表示。
为简化讨论,设
x
x
x 为一个正数。在此情形下,有:
x
−
=
1.
b
1
b
2
b
3
.
.
.
b
n
×
2
m
x_{-} = 1.b_1 b_2 b_3 ... b_n \times 2^m
x−=1.b1b2b3...bn×2m 和
x
+
=
1.
b
1
b
2
b
3
.
.
.
b
n
×
2
m
+
0.
000000...0001
⏟
n
位
×
2
m
x_{+} = 1.b_1 b_2 b_3 ... b_n \times 2^m + 0.\underbrace{000000...0001}_{n\text{ 位}} \times 2^m
x+=1.b1b2b3...bn×2m+0.n 位
000000...0001×2m ,将实数
x
x
x替换为附近的机器数(
x
−
x_{-}
x−或
x
+
x_{+}
x+)的过程称为 舍入,其中涉及的误差称为 舍入误差。
IEEE-754 并未明确规定如何舍入浮点数,但有几种不同的方法:
- 向零舍入
- 向正无穷舍入
- 向上舍入
- 向下舍入
- 向最近的浮点数舍入(向上或向下,取决于哪个更近)
- 截断舍入
我们将浮点数表示为 f l ( x ) fl(x) fl(x)。上述舍入规则可以总结如下:
x x x为正数 | x x x为负数 | |
---|---|---|
向上取整(ceil) |
f
l
(
x
)
=
x
+
fl(x)=x_+
fl(x)=x+ 向 + ∞ +\infty +∞取整 |
f
l
(
x
)
=
x
−
fl(x)=x_-
fl(x)=x− 向 0 0 0取整 |
向下取整(floor) |
f
l
(
x
)
=
x
−
fl(x)=x_-
fl(x)=x− 向 0 0 0取整 |
f
l
(
x
)
=
x
+
fl(x)=x_+
fl(x)=x+ 向 − ∞ -\infty −∞取整 |
截断舍入: f l ( x ) = x − fl(x) = x_{-} fl(x)=x−
舍入误差
注意,两个机器数之间的差距为: ∣ x + − x − ∣ = 0. 000000...0001 ⏟ n 位 × 2 m = ϵ m × 2 m |x_{+} - x_{-}| = 0.\underbrace{000000...0001}_{n\text{ 位}} \times 2^m = \epsilon_m \times 2^m ∣x+−x−∣=0.n 位 000000...0001×2m=ϵm×2m。因此,我们可以使用机器 epsilon 来限制将实数表示为机器数时的误差。
绝对误差
∣ f l ( x ) − x ∣ ≤ ∣ x + − x − ∣ = ϵ m × 2 m |fl(x) - x| \le |x_{+} - x_{-}| = \epsilon_m \times 2^m ∣fl(x)−x∣≤∣x+−x−∣=ϵm×2m
∣ f l ( x ) − x ∣ ≤ ϵ m × 2 m |fl(x) - x| \le \epsilon_m \times 2^m ∣fl(x)−x∣≤ϵm×2m
相对误差:
∣ f l ( x ) − x ∣ ∣ x ∣ ≤ ϵ m × 2 m ∣ x ∣ \dfrac{|fl(x) - x|}{|x|} \le \dfrac{\epsilon_m \times 2^m}{|x|} ∣x∣∣fl(x)−x∣≤∣x∣ϵm×2m
∣ f l ( x ) − x ∣ ∣ x ∣ ≤ ϵ m \dfrac{|fl(x) - x|}{|x|} \le \epsilon_m ∣x∣∣fl(x)−x∣≤ϵm
浮点运算的数学性质
-
不一定满足结合律: ( x + y ) + z ≠ x + ( y + z ) (x + y) + z \neq x + (y + z) (x+y)+z=x+(y+z),因为 f l ( f l ( x + y ) + z ) ≠ f l ( x + f l ( y + z ) ) fl(fl(x + y) + z) \neq fl(x + fl(y + z)) fl(fl(x+y)+z)=fl(x+fl(y+z))。
-
不一定满足分配律: z ⋅ ( x + y ) ≠ z ⋅ x + z ⋅ y z \cdot (x + y) \neq z \cdot x + z \cdot y z⋅(x+y)=z⋅x+z⋅y,因为 f l ( z ⋅ f l ( x + y ) ) ≠ f l ( f l ( z ⋅ x ) + f l ( z ⋅ y ) ) fl(z \cdot fl(x + y)) \neq fl(fl(z \cdot x) + fl(z \cdot y)) fl(z⋅fl(x+y))=fl(fl(z⋅x)+fl(z⋅y))。
-
不一定满足累积性:反复将一个非常小的数加到一个大数上可能没有任何效果。
浮点加法
将两个浮点数相加相对简单。基本思路是:
- 将两个数调整到相同的指数。
- 从前面开始进行小学加法,直到用完系统中的位数。
- 对结果进行舍入。
例如,为了在一个只有 3 位小数部分的浮点系统中将
a
=
(
1.101
)
2
×
2
1
a = (1.101)_2 \times 2^1
a=(1.101)2×21 和
b
=
(
1.001
)
2
×
2
−
1
b = (1.001)_2 \times 2^{-1}
b=(1.001)2×2−1 相加,这将如下所示:
a
=
1.101
×
2
1
b
=
0.01001
×
2
1
a
+
b
=
1.111
×
2
1
a=1.101\times 2^1 \b=0.01001\times 2^1\ a+b=1.111\times 2^1
a=1.101×21b=0.01001×21a+b=1.111×21
你会注意到,我们加了两个具有 4 位有效数字的数,结果也有 4 位有效数字。浮点加法中没有有效数字的损失。
浮点减法与灾难性消去
浮点减法的工作原理与加法类似。然而,当减去两个大小相近的数时,会出现问题。
例如,为了从
a
=
(
1.1011
)
2
×
2
1
a = (1.1011)_2 \times 2^1
a=(1.1011)2×21 中减去
b
=
(
1.1010
)
2
×
2
1
b = (1.1010)_2 \times 2^1
b=(1.1010)2×21,这将如下所示:
a
=
1.1011
?
?
?
?
×
2
1
b
=
1.1010
?
?
?
?
×
2
1
a
−
b
=
0.0001
?
?
?
?
×
2
1
a=1.1011????\times 2^1\ b=1.1010????\times 2^1\ a-b=0.0001????\times 2^1
a=1.1011????×21b=1.1010????×21a−b=0.0001????×21
当我们对结果进行归一化时,得到
1.
?
?
?
?
×
2
−
3
1.???? \times 2^{-3}
1.????×2−3。没有数据可以指示缺失的数字应该是什么。尽管浮点数将存储 4 位小数部分,但它只准确到 1 位有效数字。这种有效数字的损失称为 灾难性消去。
示例
考虑函数
f
(
x
)
=
x
2
+
1
−
1
f(x) = \sqrt{x^{2} + 1} - 1
f(x)=x2+1−1。当我们在接近零的值处评估
f
(
x
)
f(x)
f(x) 时,可能会由于浮点减法而遇到有效数字的损失。如果
x
=
1
0
−
3
x = 10^{-3}
x=10−3,使用五位小数算术,
f
(
1
0
−
3
)
=
1
0
−
6
+
1
−
1
=
0
f(10^{-3}) = \sqrt{10^{-6} + 1} - 1 = 0
f(10−3)=10−6+1−1=0。
避免有效数字损失的一种方法是消除减法:
f
(
x
)
=
x
2
+
1
−
1
=
(
x
2
+
1
−
1
)
⋅
(
x
2
+
1
+
1
)
x
2
+
1
+
1
=
x
2
(
x
2
+
1
+
1
)
f(x) = \sqrt{x^{2} + 1} - 1 = \dfrac{ (\sqrt{x^{2} + 1} - 1) \cdot (\sqrt{x^{2} + 1} + 1) } { \sqrt{x^{2} + 1} + 1 } = \dfrac{ x^{2} } { (\sqrt{x^{2} + 1} + 1) }
f(x)=x2+1−1=x2+1+1(x2+1−1)⋅(x2+1+1)=(x2+1+1)x2
因此,对于
x
=
1
0
−
3
x = 10^{-3}
x=10−3,使用五位小数算术,
f
(
1
0
−
3
)
=
1
0
−
6
2
f(10^{-3}) = \dfrac{ 10^{-6} } { 2 }
f(10−3)=210−6。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)