免责声明:不,我没有找到任何明显的答案,与我的预期相反!
在寻找代码示例时。算术平均值,我可以通过Google调出的前几个例子似乎被定义为空序列生成平均值0.0
。 (例如here和here ...)
然而,查看维基百科,Arithmetic mean被定义为空序列将产生0.0 / 0
-
A = 1/n ∑[i=1 -> n](a[i])
- 在一般情况下可能是that is NaN。
因此,如果我编写一个计算一组浮点值算术平均值的效用函数,我应该在一般情况下:
0.
?(Q)NaN
?答案 0 :(得分:34)
没有明显的答案,因为处理取决于您希望如何通知调用代码的错误。 (或者即使你想将其解释为"错误"。)
有些图书馆/程序真的不喜欢提高异常,所以要做一切信号值。在这种情况下,返回NaN(因为表达式的值在技术上是未定义的)是一个合理的选择。
如果你想要"默默地&#34>你可能也想要返回NaN。通过多个其他计算将价值推向前进。 (依赖于NaN与其他任何东西相结合的行为是"默默地" NaN。)
但是请注意,如果你为一个空序列的平均值返回NaN,那么你就需要调用函数的返回值来调用函数的代码,以确保它不是NaN - 或者立即返回或稍后。这是一个容易错过的要求,具体取决于您检查返回值的时候。
因此,其他图书馆/程序采取的错误条件应该是“嘈杂的”#34; - 如果你将一个空序列传递给一个找到序列均值的函数,那么你显然做了一些重大错误的事情,你应该清楚地知道你已经搞砸了起来。
当然,如果可以引发异常,则需要处理它们,但是您可以在更高级别执行此操作,可能会集中在更有意义的地方。根据您的程序,这可能比标准错误处理方案更容易或更多,而不是重复检查返回值。
其他人会争辩说你的函数应该对错误很有用。为了获得最大的稳健性,您可能不应该使用NaN或异常 - 您需要选择一个有意义的实际数字"作为空列表的平均值。
哪个值将高度特定于您的用例。例如,如果您的序列是差异/错误列表,则可能返回0.如果您要平均测试分数(得分0-100),您可能希望为空列表返回100 ...或者0,取决于你的哲学"开始"得分是。这一切都取决于返回值将用于什么。
鉴于此"中立的价值"根据确切的用例,值可能会变化很大,您可能希望在两个函数中实际实现它 - 一个返回NaN或引发异常的常规函数,另一个包装常规函数并识别'错误& #39;案件。这样你就可以有多个版本,每个版本都有不同的"默认"案件。 - 或者如果这是你做了很多事情的话,你甚至可以使用"默认" value是您可以传递的参数。
同样,这个问题没有一个答案:空序列的平均值是未定义的。您希望如何处理它取决于计算结果的用途:只显示或进一步计算?空列表应该是例外,还是应该安静地处理?您是否希望在发生的时间点处理特殊情况,或者您是否要提升/推迟错误处理?
答案 1 :(得分:28)
数学上,由于分母为零,因此未定义。
因为在C ++中整数除以零的行为是 undefined ,如果你在整数类型中工作,则抛出异常。
如果您在IEEE754浮点工作,则返回NaN,因为分子也将为零。 (如果分子为正,则返回+ Inf;如果分子为负,则返回-Inf。)
答案 2 :(得分:14)
我建议保持与0.0 by 0除法相同的行为,无论它是什么。实际上,人们可以采用as-if规则。通过这种方式,您可以保持与其他操作的一致性,而您无需自己做出决定。
(您甚至可以通过返回0.0 / 0来实现它,但编译器可能会以意想不到的方式对其进行优化。)
答案 3 :(得分:2)
我喜欢防御性编码,所以我会抛出异常。你可以使它成为一个特定的异常(如empty_sequence_exception)或除以0,因为分隔符是序列的长度为0。
0.0是有争议的,因为没有数据(序列)。
答案 4 :(得分:-1)
正确答案是空序列的算术平均值没有意义,因为空序列本质上是空集。没有分工是没有意义的。零肯定不是正确的答案。假设一个序列有3个成员,1,0和-1,或者是一个全零的序列。这两者的平均值为零,不应与空序列混淆。