ZeroDivisionError 整数异常,Nan 浮点数
Posted
技术标签:
【中文标题】ZeroDivisionError 整数异常,Nan 浮点数【英文标题】:ZeroDivisionError Exception with integer, Nan with float 【发布时间】:2014-05-08 23:35:30 【问题描述】:我用分裂试验了一种奇怪的行为。
some_nbr / 0 # >> ZeroDivisionError with 0 (Integer)
some_nbr / 0.0 # => NaN with 0.0 (Float)
当然,除以 0 不好,但我想弄清楚为什么用 Integer
除以零会导致异常,而用浮点数做同样的事情只会返回 Nan
。
【问题讨论】:
只有当some_nbr
本身是NaN
或0
时,NaN
才会从some_nbr/0.0
返回。如果some_nbr
是正数或负数,则它分别返回正数或负数Infinity
。可以认为 Floats 的数字系统大于 Integers 的数字系统,不仅在表示小数值方面,而且在表示 Infinite 和 indeterminate (aka NaN
) 值方面也是如此。这就是为什么当这些值是计算结果时 FLoat 不会抛出异常的原因。
【参考方案1】:
NaN
和Infinity
是“有效的”浮点值,因为保存浮点数的内存地址可以表示这些值。这是 ruby 采用的更通用的IEEE standard 的一部分。
相比之下,NaN
或 Infinity
没有有效的整数表示,因此抛出异常是合适的。
【讨论】:
这是正确的,但不是解释。它只是说,事情是这样定义的,所以它是。我认为这个答案没有任何逻辑。为什么不能有 NaN 或 Infinity 的有效表示,而 Floats 可以有它们?这个答案只是说这是因为它是这样定义的。就像一位老派老师。 @sawa 什么是充分的解释? @sawa "这是正确的,但不是解释。"这是对整数(因为它们没有 Infinity 或 NaN 的表示)而不是 Float(因为它们可以处理这些值)引发异常的原因的一个解释。当然可以问为什么 Float 和 Integer 是这样定义的,这是一个很好的问题,但是这真的可以完全回答吗?我认为我们能做的最好的就是列出这方面的应用。在以合理的方式将舍入错误处理为 0 时,您提供了一个应用程序。我提供了一个斜率计算的例子。【参考方案2】:整数0
正好为零;没有错误。由于除以零在数学上是不确定的,因此整数除以0
会引发错误是有道理的。
另一方面,float 0.0
不一定代表完全为零。它可能源自一个绝对值小到可以四舍五入为零的数字。在这种情况下,仍然定义了数学除法。当除数的绝对值很小时,突然引发错误是没有意义的。但是,在这种情况下,由于值被四舍五入,无法重现有意义的值,因此最好的方法是返回某种伪数字,例如 NaN
。
【讨论】:
“另一方面,float 0.0 不一定完全为零。”我不得不在这里不同意你的观点。如果你在 irb 中输入0.0
,那正好 0。返回1/0.0
是适当的Infinity
,而0/0.0
是适当的NaN
浮点值。这与整数算术根本不同,舍入是一个单独的问题。
我在上面加上了“代表”这个词。
还是不同意。 0.0
正好代表零。舍入是一个单独的问题。
@Matt 你没有正确理解我的意图。我的意思是,程序外部的非零值可以映射到程序内的0.0
,然后无法与最初为零的0.0
区分开来(并且完全为零)。这显然是由于四舍五入。您只是在谈论表面(即定义)。我说的是背后的原因,你没有提到。
这里是一个非零数除以 0 的例子是完全定义好的:en.wikipedia.org/wiki/Riemann_sphere 在这个系统中,Infinity
是定义好的。这与舍入无关。 IEEE 浮点系统在这方面是相似的,因为它是一个自洽系统,可以处理类似的除零。这就是为什么我说四舍五入是一个单独的问题。你所说的是这个系统的一个有用的应用,但它并没有触及问题的核心。以上是关于ZeroDivisionError 整数异常,Nan 浮点数的主要内容,如果未能解决你的问题,请参考以下文章