Подтвердить что ты не робот

Каково среднее арифметическое пустой последовательности?

Отказ от ответственности: Нет, я не нашел явного ответа, вопреки тому, что я ожидал!

При поиске примеров кода wrt. среднее арифметическое, первые несколько примеров, которые я могу включить через Google, как представляется, определены так, что пустая последовательность генерирует среднее значение 0.0. (например, здесь и здесь...)

Однако, смотря на Википедию, Арифметическое значение определяется таким образом, что пустая последовательность даст 0.0 / 0 -

 A = 1/n ∑[i=1 -> n](a[i])

- так, возможно, который является NaN в общем случае.

Итак, если я напишу функцию утилиты, которая вычисляет среднее арифметическое для набора значений с плавающей запятой, я должен в общем случае:

  • return 0. для пустой последовательности?
  • return (Q)NaN для пустой последовательности?
  • "вызывать исключение" в случае пустой последовательности?
4b9b3361

Ответ 1

Нет очевидного ответа, поскольку обработка зависит от того, как вы хотите сообщить код вызывающей ошибки. (Или даже если вы хотите интерпретировать это как "ошибку".)

Некоторые библиотеки/программы действительно не любят создавать исключения, поэтому делают все с сигнальными значениями. В этом случае возвращение NaN (потому что значение выражения технически undefined) является разумным выбором.

Вы также можете захотеть вернуть NaN, если вы хотите "бесшумно" передать значение вперед через несколько других вычислений. (Опираясь на поведение, которое NaN в сочетании с чем-либо еще "тихо" NaN.)

Но учтите, что если вы вернете NaN для среднего значения пустой последовательности, вы наложите нагрузку на код вызова, который им нужен, чтобы проверить возвращаемое значение функции, чтобы убедиться, что это не NaN - либо сразу после возврата или позже. Это требование легко пропустить, в зависимости от того, насколько вы верны при проверке возвращаемых значений.

Из-за этого другие библиотеки/программы берут точку зрения, что условия ошибки должны быть "шумными" - если вы передали пустую последовательность функции, которая находила среднее значение последовательности, то вы явно делаете что-то серьезное, и вам должно быть совершенно ясно, что вы перепутались.

Конечно, если исключения могут быть подняты, их нужно обрабатывать, но вы можете сделать это на более высоком уровне, потенциально централизованном в точке, где это имеет смысл. В зависимости от вашей программы это может быть проще или больше по строкам вашей стандартной схемы обработки ошибок, чем двойная проверка возвращаемых значений.

Другие люди будут утверждать, что ваши функции должны быть надежными для ошибки. Для максимальной надежности вы, вероятно, не должны использовать ни NaN, ни исключение - вам нужно выбрать фактическое число, которое "имеет смысл" в качестве значения для среднего пустого списка.

Какое значение будет очень специфичным для вашего варианта использования. Например, если ваша последовательность представляет собой список различий/ошибок, вы можете вернуть 0. Если вы усредняете результаты тестов (набрали 0-100), вы можете вернуть 100 для пустого списка... или 0, в зависимости от вашей философии "стартовой" оценки. Все зависит от того, для чего будет использоваться возвращаемое значение.

Учитывая, что значение этого "нейтрального" значения будет сильно изменяться на основе точного варианта использования, вы можете фактически реализовать его в двух функциях - одной общей функции, которая возвращает NaN или создает исключение, а другая, что обертывает общую функцию и распознает случай ошибки. Таким образом, вы можете иметь несколько версий, каждый из которых имеет различный случай "по умолчанию". - или если это то, что вы делаете много, вы даже можете иметь значение по умолчанию, которое вы можете передать.

Опять же, ответа на этот вопрос нет: среднее значение пустой последовательности undefined. Как вы хотите справиться с этим, это зависит от того, для чего используется результат расчета: просто покажите или выполните дальнейшие вычисления? Должен ли пустой список быть исключительным, или его следует обрабатывать спокойно? Вы хотите обрабатывать специальный случай в тот момент, когда это происходит, или вы хотите поднять/отложить обработку ошибок?

Ответ 2

Математически, он undefined, когда знаменатель равен нулю.

Поскольку поведение целочисленного деления на ноль undefined в С++, выведите исключение, если вы работаете в интегральных типах.

Если вы работаете в плавающей точке IEEE754, тогда возвращайте NaN, так как числитель также будет равен нулю. (+ Inf будет возвращен, если числитель положителен, и -Inf, если числитель отрицательный).

Ответ 3

Я предлагаю придерживаться того же поведения, что и для деления 0.0 на 0, что бы это ни было. Действительно, можно принять правило as-if. Таким образом, вы остаетесь связанными с другими операциями, и вам не нужно принимать решение самостоятельно.

(Вы даже можете реализовать его как таковое, вернув 0.0/0, но компилятор может оптимизировать это неожиданным образом.)

Ответ 4

Мне нравится защитное кодирование, поэтому я бы выбрал исключение. Вы можете сделать это либо конкретным исключением (например, empty_sequence_exception), либо делением на 0, так как делитель - это длина последовательности, которая равна 0.

0.0 является спорным, поскольку нет данных (последовательности).

Ответ 5

Правильный ответ заключается в том, что среднее арифметическое пустой последовательности не имеет смысла, поскольку пустая последовательность по существу является пустым множеством. Разделение ничего не имеет смысла. Нуль, конечно, не правильный ответ. Скажем, что последовательность имеет 3 члена, 1, 0 и -1 или последовательность всех нулей. Среднее значение обоих из них будет равным нулю, и его не следует путать с пустой последовательностью.