web-dev-qa-db-ja.com

定数としてゼロ?

私は最近このプログラミングイディオムに遭遇しました:

const float Zero = 0.0;

次に、比較で使用されます。

if (x > Zero) {..}

これが本当に効率的か、読みやすく、保守可能かを誰かが説明できますか:

if (x > 0.0) {..}

注:私はotherこの定数を定義する理由を考えることができます。Imはthisコンテキストでの使用について疑問に思っています。

15
NWS

考えられる理由は、キャッシュ、名前付け、またはタイプの強制です

キャッシング(該当なし)

比較作業中にオブジェクトを作成するコストを回避したい。 Javaの例は

BigDecimal zero = new BigDecimal ("0.0");

これにはかなり重い作成プロセスが含まれ、提供された静的メソッドを使用する方が適切です。

BigDecimal zero = BigDecimal.ZERO;

これにより、BigDecimalは初期化中にJVMによって事前にキャッシュされるため、作成コストを繰り返し発生させることなく比較できます。

あなたが説明したものの場合、プリミティブは同じ仕事をしています。これは、キャッシングとパフォーマンスの点で大部分は冗長です。

名前付け(可能性は低い)

元の開発者は、システム全体で共通の値に統一された命名規則を提供しようとしています。これには、特に一般的でない値を使用する場合にいくつかのメリットがありますが、ゼロのような基本的なものは、以前のキャッシュの場合にのみ価値があります。

強制タイプ(ほとんどの場合)

元の開発者は、特定のプリミティブ型を強制的に比較して、比較が正しい型にキャストされ、場合によっては特定のスケールにキャストされます(小数点以下の桁数)を試みています。これは問題ありませんが、単純な名前「ゼロ」はこのユースケースの詳細としては不十分であり、ZERO_1DPが意図のより適切な表現です。

29
Gary Rowe

それは「ツーリングナギング」のせいです

ここに表示されない理由として考えられるのは、多くの品質ツールがマジックナンバーの使用にフラグを付けているためです。特にコード内の複数の場所で複製されている場合は、後で変更できるように明確に表示せずに マジックナンバーを持つのは悪い習慣 がアルゴリズムにスローされることがよくあります。

したがって、これらのツールはそのような問題にフラグを立てるのに適切ですが、これらの値が無害で静的である可能性が最も高い状況では、しばしば誤検知を生成します。単に初期化値になるように。

そして、それが起こると、時々あなたは次の選択に直面します:

  • ツールで許可されている場合は、それらを誤検知としてマークします(通常、特別にフォーマットされたコメントを使用します。これは、ツールを使用していない人を困らせます)。
  • または、重要かどうかにかかわらず、これらの値を定数に抽出します。

パフォーマンスについて

それは私が推測する言語に依存しますが、これはJavaでかなり一般的であり、実際の定数である場合、コンパイル時に値がインライン化されるため、パフォーマンスへの影響はありませんstatic final。定数またはプリプロセッサマクロとして宣言されている場合、CまたはC++には影響しません。

6
haylem

これは、Zerofloat型であると明示的に定義しているので、意味があるかもしれません。

少なくともCおよびC++では、値0.0double型ですが、同等のfloat0.0fです。したがって、比較するxを仮定すると、常にfloat

x > 0.0

一方、実際にxdoubleに昇格して0.0のタイプに一致させると、問題が発生する可能性があります(特に、等式テストで)。もちろん、変換なしの比較は

x > 0.0f

同じことをする

float Zero = 0.0; // double 0.0 converted to float  
x > Zero

それでも、ユーザーに厄介なコードを書かせるよりも、コンパイラで変換の警告を有効にした方がはるかに便利だと思います。

5

まず、ゼロはfloatではなくintとして定義されています。もちろん、これは比較に影響を与えませんが、この定数を使用する他の場合には、違いが生じる可能性があります。

ここでZeroが定数として宣言されている他の理由はわかりません。これは単なるコーディングスタイルであり、その特定のプログラムの他の場所で使用されている場合は、そのスタイルに従うのが適切です。

1
superM

(コンパイラが非常に原始的でない限り)実行中はほぼ確実に効率がよく、コンパイル中はわずかに効率が悪くなります。

それがx > 0より読みやすいかどうかについて...正直に言って、正直に言って、COBOLは素晴らしいアイデアであり、一緒に仕事ができると思った人がいることを忘れないでください。 C.(噂によると、C++について同じ意見を持つプログラマーもいるということです!)言い換えれば、あなたはnotについてこの点について一般的な同意を得ようとしており、おそらくやり直す価値はありません。 。

1
Kilian Foth

これは、実際には次の場合よりも効率的、読み取り可能、または保守可能です。

_if (x > 0.0) {..}
_

generic(つまり、型固有ではない)コードを記述している場合は、おそらくそうです。 zero()関数は、代数型、またはグループw.r.tである型に適用できます。添加。それは整数かもしれません、それは浮動小数点値かもしれません、あなたの変数が、例えばそれ自身が何らかの線形空間内の関数であるなら、関数かもしれません(例えば、xはz-> a_x *の形の線形関数です) z + b_x)、次にzero()は、aとbの両方が基礎となる型のzero()である関数を提供します。

したがって、そのようなコードは、おそらくC++(おそらくzero()は非常に一般的なAFAIKではありません)、またはJulia、そしておそらく他の言語で期待されます。

0
einpoklum