免責事項:いいえ、私が期待したものとは反対に、明白な答えは見つかりませんでした!
コード例を探すとき。算術平均、私がグーグル経由で見つけることができる最初のいくつかの例は、空のシーケンスが0.0
の平均値を生成するように定義されているようです。 (例: ここ および ここ ...)
ただし、ウィキペディアを見ると、 算術平均 は、空のシーケンスが0.0 / 0
-を生成するように定義されています。
A = 1/n ∑[i=1 -> n](a[i])
-そう、おそらく、 つまりNaN 一般的な場合。
したがって、浮動小数点値のセットの算術平均を計算する効用関数を作成する場合、一般的なケースでは次のようにする必要があります。
0.
を返しますか?(Q)NaN
を返しますか?明確な答えはありません処理は、呼び出し元のコードにエラーを通知する方法によって異なるためです。 (または、これを「エラー」として解釈したい場合でも。)
一部のライブラリ/プログラムは、例外を発生させることを本当に嫌うため、シグナル値を使用してすべてを実行します。その場合、NaNを返すことは(式の値が技術的に定義されていないため)合理的な選択です。
他の複数の計算を通じて値を「サイレントに」転送したい場合は、NaNを返すこともできます。 (NaNが他のものと組み合わされた動作に依存することは「サイレント」NaNです。)
ただし、空のシーケンスの平均でNaNを返す場合は、コードの呼び出しに負担がかかり、関数の戻り値をチェックして、NaNでないことを確認する必要があります-戻った直後または後で。これは、戻り値のチェックにどれだけ注意を払っているかによっては、見逃しがちな要件です。
このため、他のライブラリ/プログラムは、エラー条件は「ノイズが多い」はずであるという観点を取ります。シーケンスの平均を見つける関数に空のシーケンスを渡した場合、明らかに何か大きな問題が発生しているはずです。あなたが台無しにしたことをあなたに十分に明らかにしてください。
もちろん、例外が発生する可能性がある場合は、それらを処理する必要がありますが、より高いレベルでそれを行うことができ、より意味のあるポイントに集中化される可能性があります。プログラムによっては、戻り値を再確認するよりも、標準のエラー処理スキームに沿った方が簡単な場合もあります。
他の人々はあなたの関数がエラーに対して頑強であるべきだと主張するでしょう。最大限の堅牢性を得るには、NaNも例外も使用しないでください。空のリストの平均値として、「意味のある」実際の数値を選択する必要があります。
どの値が非常にユースケースに固有になるか。たとえば、シーケンスが差異/エラーのリストである場合、0を返す場合があります。テストスコア(0から100のスコア)を平均している場合、空のリストの場合は100を返します...または0、 「開始」スコアの哲学が何であるかに応じて。それはすべて、戻り値が何に使用されるかによって異なります。
この「ニュートラル」値の値は正確なユースケースに基づいて大きく変動するため、実際には2つの関数で実装することをお勧めします。1つはNaNを返すか例外を発生させる一般的な関数で、もう1つは一般的な関数をラップします。機能し、「エラー」の場合を認識します。このようにして、それぞれが異なる「デフォルト」ケースを持つ複数のバージョンを持つことができます。 -または、これが頻繁に行うことである場合は、「デフォルト」値を渡すことができるパラメーターにすることもできます。
繰り返しますが、この質問に対する単一の答えはありません。空のシーケンスの平均は定義されていません。それをどのように処理したいかは、計算の結果が何に使用されているかに密接に依存します:表示するだけですか、それともさらに計算しますか?空のリストは例外的である必要がありますか、それとも静かに処理する必要がありますか?特別なケースが発生した時点で処理しますか、それともエラー処理を引き上げ/延期しますか?
数学的には、分母がゼロであるため、未定義です。
C++では整数除算の動作はndefinedであるため、整数型で作業している場合は例外をスローします。
IEEE754浮動小数点で作業している場合は、numeratorもゼロになるため、NaNを返します。 (分子が正の場合は+ Infが返され、分子が負の場合は-Infが返されます)。
0.0 x 0の除算と同じ動作を維持することをお勧めしますそれが何であれ。実際、as-ifルールを採用することができます。このようにして、他の操作との一貫性を保ち、自分で決定を下す必要がありません。
(0.0/0を返すことで、そのように実装することもできますが、コンパイラーはこれを予期しない方法で最適化する可能性があります。)
私は防御的なコーディングが好きなので、例外をスローします。除算はシーケンスの長さである0であるため、特定の例外(empty_sequence_exceptionなど)または0による除算のいずれかにすることができます。
データ(シーケンス)がないため、0.0は議論の余地があります。