非规范化数 - IEEE 754浮点数

19
所以我正在尝试学习更多关于 IEEE 754 标准中浮点数定义的非规范化数字。通过谷歌搜索结果,我已经阅读了几篇文章,并查看了几个 StackOverFlow 帖子。然而,我仍有一些未解答的问题。
首先,简单回顾一下我对非规范化浮点数的理解:
数字的精度比规范化数字低,并且比规范化数字小(在大小方面)。
基本上,非规范化浮点数能够表示任何浮点值可以表示的最小(在大小方面)数字。
这听起来正确吗?还有其他方面吗?
我读到过:
在许多平台上,使用非规范化数字会带来性能成本。
对此有什么评论吗?
我还在一篇文章中读到过:
应该“避免规范化和非规范化数字之间的重叠”。
对此有什么评论吗?
在IEEE标准的某些演示中,当浮点数范围呈现时,非规格化值被排除在外,并且表格被标记为“有效范围”,几乎好像演示者在想:“我们知道非规格化数字可以表示最小可能的浮点值,但由于非规格化数字的某些缺点,我们选择将它们从适合常见使用情况的范围中排除”——好像非规格化数字并不常用。
我猜我只是一直觉得在大多数情况下使用非规格化数字并不是件好事?
如果我必须自己回答这个问题,我会认为:
使用非规格化数字是好的,因为你可以表示最小(按大小)的数字-只要精度不重要,而且你不会将它们与规格化数字混淆,并且应用程序的性能符合要求。
使用非规格化数字是不好的,因为大多数应用程序不需要如此小的表示-精度损失是有害的,并且你很容易通过将其与规格化数字混淆来自食其果,而且在大多数情况下,性能不值得代价。
对这两个答案有什么评论吗?关于非规格化数字,我还可能遗漏或不理解什么?

3
请参考该问题的深入讨论,了解denormals及其处理方法:https://dev59.com/yGox5IYBdhLWcg3wSCRW - fig
1个回答

21
基本上,非规范化浮点数具有表示任何浮点数可以表示的最小值(按大小排序)的能力。
是的。
在许多平台上使用非规范化数会带来性能成本。
惩罚在不同处理器上不同,但可能高达2个数量级。 原因是与此建议相同:
应该“避免规范化和非规范化数字之间的重叠”。
这是关键:非规范化数是IEEE-754浮点格式中的固定点“微格式”。 在正常数字中,指数表示二进制点的位置。 对于双精度,非规范化数字以2-1074的指数形式包含最后52位的固定点表示。
因此,非规范化数很慢,因为它们需要特殊处理。 在实践中,它们很少发生,并且芯片制造商不喜欢在罕见情况下花费太多宝贵资源。
将非规范化数与规范化数混合使用很慢,因为您正在混合格式,并且必须执行两者之间的转换的附加步骤。
我想我只是一直有这样的印象,使用非规范化数在大多数情况下并不好?

非规范化数被创建出来的主要目的是:逐渐下溢。它是一种保持微小数字之间相对差异很小的方法。如果你直接从最小的规范化数到零(突然下溢),相对变化就是无穷大的。如果你在下溢时转换到非规范化数,则相对变化仍然不完全准确,但至少更合理。而且这种差异会显示在计算中。

换句话说,浮点数并不均匀分布。连续的二次幂之间始终有相同数量的数字:252(对于双精度)。因此,在没有非规范化数的情况下,总会存在一个缺口,即0和最小浮点数之间的距离是最小两个数字之间差异的252倍。而非规范化数则填补了这个缺口。

作为关于突然下溢和逐渐下溢效果的例子,看一下数学上等价的x == yx - y == 0。如果xy非常小但是不同,并且使用突然下溢,那么如果它们的差异小于最小截止值,它们的差异将为零,因此等价性被破坏。
通过逐渐下溢,两个非常小但不同的正常数字之间的差异变成了一个非规格化数,仍然不为零。等价性得到了保持。
因此,有意使用非规格化数并不建议,因为它们只是在特殊情况下作为备份机制而设计的

1
在我熟悉的任何处理器上,将次正常值与正常值混合使用不会比仅使用次正常值具有更大的性能惩罚。 - Eric Postpischil
2
尽管次正常值很少见,但在某些应用中,它们比预期出现的更频繁。一个不太罕见的例子是回声效果(以及其他信号处理滤波器),当音频输入停止时。如果没有新的输入来保持值处于正常范围,过滤器中的残留值会随着时间的推移而减少并达到次正常范围。 - Eric Postpischil
我喜欢x == yx - y == 0的例子。如果我们忽略非数字和无穷大,IEEE浮点数是否具有这种属性?我的意思是,只有当x == y时,x - y == 0才成立。 - Jeppe Stig Nielsen
1
@JeppeStigNielsen 是的,对于所有IEEE浮点数都是正确的,唯一的例外是x,y = +inf,+infx,y = -inf,-inf。如果xy是NaN,则它可以工作,因为在这种情况下x-y是NaN,所以x-y == 0是假的,并且根据定义x == y也是假的。 - Jeffrey Sax
据我所知,IEEE-754 的意图是将 32 位和 64 位浮点值解包成一个格式,该格式不假定前导“1”,并使用该格式执行操作。完成一系列操作后,该序列的结果将转换回 32 位或 64 位格式。在多个操作被链接在一起的常见情况下,这种方法可以最小化使用非规格化数的开销,因为中间值格式不必对它们进行任何特殊处理。 - supercat
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接