为什么IEEE 754标准使用127的偏置值?

9

在处理整数的过度表示时,我使用2n-1的偏差。然而,IEEE 754标准使用的是2n-1 - 1。

我能想到的唯一好处就是更大的正数范围。是否还有其他决策的原因?

1个回答

10
原因是无穷大/非数和渐进下溢。
如果要使用指数来表示整数(n >= 0)和小数(n < 0),那么你需要一个指数来表示2^0 = 1。所以剩下的范围是奇数,让你在小数或整数中选择更大的范围。 对于单精度浮点数,我们有256个值,不包括指数为0的值(255)。现在,IEEE754保留了最高指数(255)用于特殊值:+-无穷大和NaN(非数字)来表示失败。所以我们又回到了偶数(254)的范围内,但偏差更小了。
第二个原因是渐进下溢。标准规定通常所有的数都是归一化的,这意味着指数表示第一位的位置。为了增加比特数,第一位通常没有设置,而是被隐含(隐藏的比特):指数比特后的第一位是数字的第二个比特,第一个始终是二进制1。如果强制进行归一化,则会遇到无法编码零的问题,即使将零编码为特殊值,数值精度也会受到影响。+-无穷大(最高指数)表明某些东西出了问题,但对于太小的数而言,渐进下溢成为零是完全正常的,因此很容易忽略作为可能的问题。所以标准的设计者Kahan决定引入非规格化数或次规格化数,并且它们应该包括1/MAX_FLOAT。
编辑:Allan问为什么如果将零编码为特殊值,则“数值精度会受到影响”。我最好把它说成“数值精度仍然会受到影响”。事实上,这是历史上DEC VAX浮点格式的实现方式。如果原始位编码中的指数字段为0,则被视为零。例如,我现在使用仍然广泛用于GPU的32位格式。
X 00000000 XXXXXXXXXXXXXXXXXXXXXXX

在这种情况下,右侧的尾数字段的内容可以完全忽略,通常填充为零。左侧的符号字段可以有效地区分正常的零和“负零”(您可以通过像-1.0/0.0或舍入负数之类的操作获得负零)。
IEEE 754标准中的渐近下溢和次规范使用了尾数字段。
X 00000000 00000000000000000000000

其中一个二进制位组合为零。所有其他的二进制位组合都是有效的,更实用的是,如果结果下溢,你会受到警告。

那么这有什么意义呢?

考虑不同的数字

A 0 00000009 10010101111001111111111  
B 0 00000009 10010101111100001010000

它们是有效的浮点数成员,非常小但仍然是有限的。但是,您会发现前11位是相同的。如果现在您减去A-B或B-A,第一个有效比特将离开较低的指数范围,因此结果没有逐渐下溢... 0。所以A!= B,但A-B = 0。糟糕。无数人陷入了这个陷阱,可以认为他们从未意识到这一点。乘法或除法也是如此:您需要添加或减去指数,如果它低于较低阈值:0。并且如您所知道的:0 * everything = 0。您可能拥有STXYZ,并且一旦一个子乘积为0,即使完全有效甚至巨大的数字是正确的结果,结果也为0。应该说,由于舍入,这些异常情况永远无法完全避免,但通过逐渐下溢,它们变得罕见。非常罕见。

1
我想知道处理非规格化数的硬件效率与在1.00B-127之后有下一个更大的数字1.00B-126、然后是1.10B-126、然后是1.00B-125、1.01B-125等的硬件效率相比如何。换句话说,将每个数字四舍五入到最接近的1.00B-127。这将避免没有非规格化数时通常会出现的奇怪下溢行为,尽管它不会提供额外范围的好处。我猜测范围并不像确保(a-b)仅在(a==b)时为零那样重要,因此如果舍入比非规格化数更便宜,那么这可能是一种胜利。 - supercat
奇怪的是参数在时间上重复出现。事实上,在IEEE 754标准化的发明过程中,Kahan(使用次正规数)和DEC VAX格式之间进行了一场争斗,后者几乎完全像IEEE 754,但仅使用零。 - Thorsten S.
请不要惊讶,我的回答似乎有点奇怪,因为我正在与supercat的回答不同步地编辑我的问题。有一次我按了回车键,所以它在我还没有准备好的时候显示出来了,还有一次我达到了5分钟限制。@supercat:虽然非对称零确实是我渴望的东西,但Stack Overflow不喜欢冗长的讨论,所以我现在就停止这里。 - Thorsten S.
@ThorstenS. 你能解释一下为什么“如果将零编码为特殊值,数值精度会受到影响”吗? - Allan Ruin
@AllanRuin 希望这有所帮助。 - Thorsten S.
显示剩余3条评论

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