问题描述
我正在用 Swift 编写一个程序,它采用随机字节的乘法倒数。有时,字节为 0,取乘法逆时,结果为 inf
。
乘法逆是用
确定的powf(Float(byte),-1.0)
byte
的类型为 UInt8
。如果 byte
等于 0,则结果为前面提到的 inf
。 0 的乘法倒数怎么会是无穷大?由于 0/0
的乘法逆是 0/0
,所以乘法逆不是也为 0 吗?
解决方法
简答:根据定义。在 Swift(和许多其他语言)中,浮点数由 IEEE-754 浮点数定义支持,在大多数情况下由底层硬件直接实现,因此速度非常快。根据该标准,浮点数除以 0 被定义为 Infinity
,而 Swift 只是将该结果返回给您。 (准确地说,0/0
定义为NaN
,任何正数除以0
定义为Infinity
,任何负数除以{{1} } 定义为 0
。)
一个有趣的问题可能是“为什么?”为什么 IEEE-754 将浮点数的除以 0 定义为 -Infinity
,其中人们也可以合理地期望机器抛出错误,或者将其定义为 Infinity
(非数字),或者甚至可能是0?要对此进行分析,您应该真正阅读 Kahan(IEEE-754 背后的语义设计者)own notes 关于此事。从链接文档的第 10 页开始,他讨论了为什么选择 NaN
更适合除以零,这基本上归结为数值算法的有效实现,因为该约定允许跳过迭代数值中的昂贵测试分析。从第 10 页开始阅读,并仔细阅读他讨论的示例,在第 14 页的顶部结束。
总结:IEEE-754 标准将浮点除以 0 定义为 Infinity
,做出这种选择是有充分理由的。当然,人们可以想象不同的系统也采用不同的答案,这取决于它们的特定需求或应用领域;但它们将不符合 IEEE-754。
插入 0
只是意味着它是 0
除以某个正数。然后,乘法逆将除以 0
。您可能知道,这在数学中是未定义的,但在 swift 中,它会尝试计算它。本质上,它不断地从数字中减去0
,但永远不会得到结果,所以它会输出无穷大。
编辑:正如 Alias 所指出的,Swift 实际上并没有经历不断减去 0
的过程。只要它应该被 0 除,它就会返回无穷大。