空序列的算术平均值是多少?
What is the arithmetic mean of an empty sequence?
免责声明:不,我没有找到任何明显的答案,这与我的预期相反!
在寻找代码示例时。算术平均值,我可以通过 Google 找到的前几个示例似乎被定义为空序列生成 0.0
的平均值。 (例如 here and here ...)
然而,查看维基百科,Arithmetic mean 被定义为空序列将产生 0.0 / 0
--
A = 1/n ∑[i=1 -> n](a[i])
-- 因此,一般情况下可能 that is NaN。
因此,如果我编写一个效用函数来计算一组浮点值的算术平均值,在一般情况下我应该:
- return
0.
为空序列?
- return
(Q)NaN
为空序列?
- "throw an exception" 如果序列为空?
在数学上,它是未定义的,因为分母为零。
因为整数除以零的行为在 C++ 中是未定义,如果您使用整数类型,则抛出异常。
如果您使用的是 IEEE754 浮点数,那么 return NaN 因为 numerator 也将为零。 (如果分子为正,+Inf 将被 returned,如果分子为负,则为 -Inf)。
我喜欢防御性编码,所以我会抛出异常。您可以将其设为特定异常(如 empty_sequence_exception)或除以 0,因为除数是序列的长度,即 0.
0.0 有争议,因为没有数据(序列)。
我建议保持与 0.0 x 0 划分相同的行为,不管它是什么。事实上,人们可以采用假设规则。这样您就可以与其他操作保持一致,而不必自己做出决定。
(您甚至可以通过返回 0.0/0 来实现它,但编译器可能会以意想不到的方式对其进行优化。)
没有明显的答案,因为处理取决于您希望如何通知调用代码错误。 (或者即使你想将其解释为 "error"。)
有些 libraries/programs 真的不喜欢引发异常,所以用信号值做所有事情。在那种情况下,returning NaN(因为表达式的值在技术上未定义)是一个合理的选择。
如果您想 "silently" 通过其他多个计算将值向前推,您可能还想 return NaN。 (依赖于 NaN 与其他任何东西结合的行为是 "silently" NaN。)
但请注意,如果您将 return NaN 作为空序列的平均值,则会给调用代码带来负担,它们需要检查函数的 return 值以确保它不是 NaN - 在 return 之后或之后立即出现。这是一个很容易错过的要求,具体取决于您在检查 return 值时的挑剔程度。
因此,其他 libraries/programs 认为错误条件应该是 "noisy" - 如果您将一个空序列传递给一个正在寻找序列平均值的函数,那么您已经显然做错了什么,应该让你清楚地知道你搞砸了。
当然,如果可以引发异常,则需要对其进行处理,但您可以在更高级别执行此操作,可能集中在更有意义的位置。根据您的程序,这可能比双重检查 return 值更容易或更符合您的标准错误处理方案。
其他人会争辩说您的函数应该对错误具有鲁棒性。为了获得最大的稳健性,您可能不应该使用 NaN 或异常 - 您需要选择一个 "makes sense" 的实际数字作为空列表平均值的值。
哪个值将高度特定于您的用例。例如,如果您的序列是 differences/errors 的列表,您可能希望 return 0。如果您计算考试分数的平均值(得分 0-100),您可能希望 return 100对于空列表...或 0,具体取决于您对 "starting" 分数的看法。这完全取决于 return 值的用途。
鉴于此 "neutral" 值的值将根据具体用例变化很大,您可能希望在两个函数中实际实现它 - 一个 returns 的通用函数NaN 或引发异常,以及另一个包装一般函数并识别 'error' 情况的异常。这样您就可以拥有多个版本,每个版本都有不同的 "default" 大小写。 -- 或者如果这是您经常做的事情,您甚至可以将 "default" 值作为您可以传递的参数。
同样,这个问题没有单一的答案:空序列的平均值是未定义的。您希望如何处理它在很大程度上取决于计算结果的用途:只是显示,还是进一步计算?一个空列表应该是例外,还是应该安静地处理?您是想在特殊情况发生时及时处理,还是想 hoist/defer 错误处理?
正确答案是空序列的算术平均值没有意义,因为空序列本质上是一个空集。什么都没有的划分是没有意义的。零当然不是正确答案。假设一个序列有 3 个成员,1、0 和 -1,或者是一个全为零的序列。这两者的均值为零,不应与空序列混淆。
免责声明:不,我没有找到任何明显的答案,这与我的预期相反!
在寻找代码示例时。算术平均值,我可以通过 Google 找到的前几个示例似乎被定义为空序列生成 0.0
的平均值。 (例如 here and here ...)
然而,查看维基百科,Arithmetic mean 被定义为空序列将产生 0.0 / 0
--
A = 1/n ∑[i=1 -> n](a[i])
-- 因此,一般情况下可能 that is NaN。
因此,如果我编写一个效用函数来计算一组浮点值的算术平均值,在一般情况下我应该:
- return
0.
为空序列? - return
(Q)NaN
为空序列? - "throw an exception" 如果序列为空?
在数学上,它是未定义的,因为分母为零。
因为整数除以零的行为在 C++ 中是未定义,如果您使用整数类型,则抛出异常。
如果您使用的是 IEEE754 浮点数,那么 return NaN 因为 numerator 也将为零。 (如果分子为正,+Inf 将被 returned,如果分子为负,则为 -Inf)。
我喜欢防御性编码,所以我会抛出异常。您可以将其设为特定异常(如 empty_sequence_exception)或除以 0,因为除数是序列的长度,即 0.
0.0 有争议,因为没有数据(序列)。
我建议保持与 0.0 x 0 划分相同的行为,不管它是什么。事实上,人们可以采用假设规则。这样您就可以与其他操作保持一致,而不必自己做出决定。
(您甚至可以通过返回 0.0/0 来实现它,但编译器可能会以意想不到的方式对其进行优化。)
没有明显的答案,因为处理取决于您希望如何通知调用代码错误。 (或者即使你想将其解释为 "error"。)
有些 libraries/programs 真的不喜欢引发异常,所以用信号值做所有事情。在那种情况下,returning NaN(因为表达式的值在技术上未定义)是一个合理的选择。
如果您想 "silently" 通过其他多个计算将值向前推,您可能还想 return NaN。 (依赖于 NaN 与其他任何东西结合的行为是 "silently" NaN。)
但请注意,如果您将 return NaN 作为空序列的平均值,则会给调用代码带来负担,它们需要检查函数的 return 值以确保它不是 NaN - 在 return 之后或之后立即出现。这是一个很容易错过的要求,具体取决于您在检查 return 值时的挑剔程度。
因此,其他 libraries/programs 认为错误条件应该是 "noisy" - 如果您将一个空序列传递给一个正在寻找序列平均值的函数,那么您已经显然做错了什么,应该让你清楚地知道你搞砸了。
当然,如果可以引发异常,则需要对其进行处理,但您可以在更高级别执行此操作,可能集中在更有意义的位置。根据您的程序,这可能比双重检查 return 值更容易或更符合您的标准错误处理方案。
其他人会争辩说您的函数应该对错误具有鲁棒性。为了获得最大的稳健性,您可能不应该使用 NaN 或异常 - 您需要选择一个 "makes sense" 的实际数字作为空列表平均值的值。
哪个值将高度特定于您的用例。例如,如果您的序列是 differences/errors 的列表,您可能希望 return 0。如果您计算考试分数的平均值(得分 0-100),您可能希望 return 100对于空列表...或 0,具体取决于您对 "starting" 分数的看法。这完全取决于 return 值的用途。
鉴于此 "neutral" 值的值将根据具体用例变化很大,您可能希望在两个函数中实际实现它 - 一个 returns 的通用函数NaN 或引发异常,以及另一个包装一般函数并识别 'error' 情况的异常。这样您就可以拥有多个版本,每个版本都有不同的 "default" 大小写。 -- 或者如果这是您经常做的事情,您甚至可以将 "default" 值作为您可以传递的参数。
同样,这个问题没有单一的答案:空序列的平均值是未定义的。您希望如何处理它在很大程度上取决于计算结果的用途:只是显示,还是进一步计算?一个空列表应该是例外,还是应该安静地处理?您是想在特殊情况发生时及时处理,还是想 hoist/defer 错误处理?
正确答案是空序列的算术平均值没有意义,因为空序列本质上是一个空集。什么都没有的划分是没有意义的。零当然不是正确答案。假设一个序列有 3 个成员,1、0 和 -1,或者是一个全为零的序列。这两者的均值为零,不应与空序列混淆。