7

複雑な数学をコーディングするための一般的に受け入れられている最良のアプローチはありますか? 例えば:

double someNumber = .123 + .456 * Math.Pow(Math.E, .789 * Math.Pow((homeIndex + .22), .012));

これは、数値をハードコーディングしても問題ないポイントですか? それとも、各数値に定数を関連付ける必要がありますか? または、計算をconfigに保存して何らかの方法で呼び出すなど、別の方法もありますか?

このようなコードがたくさんあるので、保守しやすいようにしています。

注: 上記の例は 1 行だけです。これらのコード行は数十行または数百行になります。数値が変わるだけでなく、式も変わる可能性があります。

4

8 に答える 8

19

一般に、定数には 2 種類あります。1 つは実装にとって意味のあるもので、もう 1 つはビジネス ロジックにとって意味のあるものです。

第 1 種の定数をハードコードしても問題ありません。これらは、アルゴリズムを理解するためのプライベートなものです。たとえば、三分探索を使用していて、間隔を 3 つの部分に分割する必要がある場合は、ハードコーディングされた値で分割するの3が適切な方法です。

一方、プログラムのコードの外で意味を持つ定数は、ハードコードするべきではありません: それらに明示的な名前を与えることで、あなたが退職した後もあなたのコードを保守する誰かが、書き直すことなく正しい変更を行う可能性をゼロでなくすることができます。何もないところから始めたり、電子メールで助けを求めたりします。

于 2013-09-10T18:06:17.690 に答える
2

私はたいてい、コードを書いてから 6 か月後、睡眠不足で午前 3 時にコードを保守して修正できるかどうか自問します。それは私によく役立っています。あなたの式を見ると、できるかどうかわかりません。

昔、保険業界で働いていました。私の同僚の何人かは、数理式をコードに変換する任務を負っていました。最初は FORTRAN、後に C でした。数学とプログラミングのスキルは、同僚によって異なりました。私が学んだことは、彼らのコードを見直す次のことでした:

  • 実際の式をコードで文書化します。それがなければ、何年も後に実際の式を思い出すのに苦労するでしょう. 外部ドキュメントが失われたり、古くなったり、単にアクセスできなくなったりする可能性があります。
  • 文書化、再利用、テストが可能な個別のコンポーネントに数式を分割します。
  • 定数を使用して方程式を文書化します。マジックナンバーはコンテキストがほとんどなく、多くの場合、他の開発者が理解するには既存の知識が必要です。
  • 可能であれば、コンパイラーに依存してコードを最適化してください。優れたコンパイラは、メソッドをインライン化し、重複を減らし、特定のアーキテクチャ用にコードを最適化します。場合によっては、パフォーマンスを向上させるために式の一部を複製することがあります。

とは言うものの、特に特定のコンテキスト内でそれらの値がよく理解されている場合は、ハードコーディングが物事を単純化するだけの場合があります。たとえば、値をドルに変換しているため、何かを 100 または 1000 で除算 (または乗算) します。もう 1 つは、時間を秒に変換したい場合に 3600 を掛けることです。それらの意味は、より大きな文脈から暗示されることがよくあります。以下は、マジック ナンバー 100 についてあまり語っていません。

public static double a(double b, double c)
{
     return (b - c) * 100;
} 

しかし、以下はより良いヒントを与えるかもしれません:

public static double calculateAmountInCents(double amountDue, double amountPaid)
{
     return (amountDue - amountPaid) * 100;
}
于 2013-09-10T18:56:10.047 に答える
1

このようにインラインのままにしないでください。

一定であるため、再利用、簡単な検索、簡単な変更が可能で、誰かがあなたのコードを初めて見たときに、より適切に維持できます。

カスタマイズできる/する必要がある場合は、構成を行うことができます。顧客が値を変更すると、どのような影響がありますか? その選択肢を与えない方がよい場合もあります。彼らは自分でそれを変更し、物事がうまくいかないときにあなたを責める可能性があります. 繰り返しになりますが、リリース スケジュールよりも頻繁に流動的になる可能性があります。

于 2013-09-10T18:01:32.363 に答える
0

行の計算が次の開発者に何かを説明する場合は、そのままにしておくことができます。それ以外の場合は、コードまたは構成ファイルで定数値を計算したほうがよいでしょう。

次のような製品コードの 1 行を見つけました。

int interval = 1 * 60 * 60 * 1000; 

コメントがなければ、元の開発者が1 hourの値を見るのではなく、ミリ秒単位で意味していたことは難しくありませんでし3600000た。

IMO そのようなシナリオでは、計算を省略した方がよい場合があります。

于 2013-09-10T18:09:09.250 に答える
0

Its worth noting that the C# compiler (or is it the CLR) will automatically inline 1 line methods so if you can extract certain formulas into one liners you can just extract them as methods without any performance loss.

EDIT:

Constants and such more or less depends on the team and the quantity of use. Obviously if you're using the same hard-coded number more than once, constant it. However if you're writing a formula that its likely only you will ever edit (small team) then hard coding the values is fine. It all depends on your teams views on documentation and maintenance.

于 2013-09-10T18:03:24.240 に答える