C++ 空序列的算术平均值是多少?

C++ 空序列的算术平均值是多少?,c++,math,floating-point,nan,C++,Math,Floating Point,Nan,免责声明:不,我没有找到任何明显的答案,与我的预期相反 在查找代码示例时,请使用wrt。算术平均值,我可以通过Google找到的前几个例子,似乎是这样定义的:空序列生成的平均值为0.0。(例如和……) 然而,看看维基百科,定义的是空序列将产生0.0/0-- --因此,在一般情况下,可能是这样 因此,如果我编写一个实用函数来计算一组浮点值的算术平均值,在一般情况下,我应该: 为空序列返回0. 返回空序列的(Q)NaN 如果序列为空,“抛出异常” 从数学上讲,分母是零,所以它没有定义 由于C++中

免责声明:不,我没有找到任何明显的答案,与我的预期相反

在查找代码示例时,请使用wrt。算术平均值,我可以通过Google找到的前几个例子,似乎是这样定义的:空序列生成的平均值为
0.0
。(例如和……)

然而,看看维基百科,定义的是空序列将产生
0.0/0
--

--因此,在一般情况下,可能是这样

因此,如果我编写一个实用函数来计算一组浮点值的算术平均值,在一般情况下,我应该:

  • 为空序列返回
    0.
  • 返回空序列的
    (Q)NaN
  • 如果序列为空,“抛出异常”

从数学上讲,分母是零,所以它没有定义

由于C++中的整数除以零的行为未定义,如果您使用整数类型,则抛出异常。


如果您使用的是IEEE754浮点,则返回NaN,因为分子也将为零。(如果分子为正,则返回+Inf;如果分子为负,则返回-Inf)。

我喜欢防御性编码,因此我会抛出一个异常。您可以将其设置为特定异常(如空序列异常)或除以0,因为除法器是序列的长度,即0


0.0是有争议的,因为没有数据(序列)。

我建议保持与0.0乘0除法相同的行为,不管它是什么。事实上,我们可以采用“似乎”规则。这样,您就可以与其他操作保持一致,而不必自己做出决定


(您甚至可以通过返回0.0/0来实现它,但编译器可能会以意外的方式对此进行优化。)

没有明显的答案,因为处理取决于您希望如何将错误通知调用代码。(或者,即使您想将其解释为“错误”。)

有些库/程序真的不喜欢引发异常,所以使用信号值做任何事情。在这种情况下,返回NaN(因为表达式的值在技术上是未定义的)是一个合理的选择

如果希望通过多个其他计算“静默”地向前推送值,则可能还希望返回NaN。(依赖于NaN与其他事物结合的行为是“无声的”NaN。)

但请注意,如果返回空序列的平均值为NaN,则会给调用代码带来负担,因为它们需要检查函数的返回值,以确保它不是NaN—无论是在返回时还是稍后。这是一个很容易忽略的要求,这取决于您在检查返回值时有多挑剔

正因为如此,其他库/程序认为错误条件应该是“有噪声的”——如果你将一个空序列传递给一个正在寻找序列平均值的函数,那么你显然做了一些严重错误的事情,你应该清楚地知道你把事情搞砸了

当然,如果可以引发异常,则需要对其进行处理,但您可以在更高的级别上进行处理,可能集中在更合理的位置。根据您的程序,这可能比双重检查返回值更容易或更符合您的标准错误处理方案

其他人会争辩说,您的函数应该对错误具有鲁棒性。为了获得最大的健壮性,您可能不应该使用NaN或异常-您需要选择一个“有意义”的实际数字作为空列表的平均值

哪个值对于您的用例是高度特定的。例如,如果序列是差异/错误列表,则可能需要返回0。如果你是平均测试分数(分数为0-100),你可能想返回100作为一个空列表。。。或者0,这取决于你对“开始”分数的理解。这完全取决于返回值的用途

考虑到这个“中性”值的值将根据具体的用例高度可变,您可能希望在两个函数中实际实现它——一个是返回NaN或引发异常的通用函数,另一个是包装通用函数并识别“错误”情况的函数。这样,您可以有多个版本,每个版本都有不同的“默认”大小写。-或者,如果这是您经常做的事情,您甚至可以将“default”值作为您可以传递的参数


同样,这个问题没有一个单一的答案:空序列的平均值是未定义的。您希望如何处理它与计算结果的用途密切相关:只是显示,还是进一步计算?空名单是例外,还是应该安静地处理?您是希望在特殊情况发生时处理它,还是希望提升/延迟错误处理

正确答案是空序列的算术平均值没有意义,因为空序列本质上是一个空集。一事无成是毫无意义的。零肯定不是一个正确的答案。假设一个序列有3个成员,1,0和-1,或者是一个全零序列。这两者的平均值都为零,不应与空序列混淆

仅供参考numpy为此返回
nan
np.mean(np.array([]))
因此wikipedia看起来是正确的,我会说它是未定义的,因为它是0/0。你是否想抛出异常,更重要的是你编写它的环境中的约定。@EdChum:numpy正确地分析了它。@Bathsheba我也这么认为,从数学角度讲,这对我来说很有意义,异常端是一个实现detail@EdChum,但请注意,整数除以零是未定义的行为
 A = 1/n ∑[i=1 -> n](a[i])