定数としてゼロ?


15

最近、このプログラミングのイディオムに出会いました。

const float Zero = 0.0;

これは比較で使用されます:

if (x > Zero) {..}

これが実際よりも効率的であるか、読み取り可能または保守可能であるかを誰でも説明できますか?

if (x > 0.0) {..}

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


31
開発者は、数学の法則が異なる宇宙にコードを移植することを計画していますか?
vaughandroid

6
しかし、真剣に、これには単一の正当な理由を考えることはできません。...私が思い付くことができる唯一の説明は、オーバー熱心なコーディング標準であるか、聞いたことがいくつかの開発者は、「マジックナンバーは悪い」が、(マジックナンバーを構成するであろうか、どのような)理由を理解していない
vaughandroid

@Baqueta-代替の宇宙?彼らはすでにそこに住んでいたと思います!マジックナンバーについては、私は同意しますが、0と1を除くすべてを一定にする必要があるという経験則を使用します。
NWS

1
xtypeを持っている場合float、にx > 0.0強制的に昇格させますがdouble、効率が低下する可能性があります。それはあなたの定数(例えば正しい型を持っているだけで確認することのために、名前付き定数かかわらを使用するための十分な理由ではない0ffloat(0)またはdecltype(x)(0))。
マイクシーモア

1
@JoSo:公平を期すために、タイプは13.37でなくfloatdoubleです。だからあなたが望むならfloatそれはあなたの家庭教師が正しかったと考えられます。一部のコンテキスト(フロートへの割り当てなど)13.37は暗黙的に必要なものに変換されfloatますが、他のコンテキスト(テンプレートタイプの推論など)では変換されませんが、static const float常に意図したタイプとして開始されます。したがって、よりタイプセーフです。あなたの心、そうだろう13.37f!ただし、「タイプセーフ」以外にマクロを回避する理由は他にもあります。そのため、先生があなたに不適切な議論を与えていた可能性があります。
スティーブジェソップ

回答:


29

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

キャッシング(適用外)

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

BigDecimal zero = new BigDecimal ("0.0");

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

BigDecimal zero = BigDecimal.ZERO;

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

説明した内容の場合、プリミティブは同じジョブを実行しています。これは、キャッシングとパフォーマンスの点で大幅に冗長です。

命名(可能性は低い)

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

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

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


2
強制タイプの場合は+1。演算子のオーバーロード、定数の定義、および使用を許可するC ++などの言語で追加しtypedef、変数の型を正確に1箇所に保持し、コードを変更せずに変数を変更できるようにします。
-Blrfl

3
タイプを強制することは彼らが試みていたものではない可能性が高いですが、これはなぜそれができるのかについての最良の説明です!
NWS

7
型を強制するには、おそらく単にを使用します0.0f
Svish

型を強制することはvb.netで役立つ場合があります。vb.netでは、バイトに対してビット演算子を実行するとバイトの結果が得られます。と言うbyteVar1 = byteVar2 Or CB128よりも少しいいようですbyteVar1 = byteVar2 Or CByte(128)。もちろん、バイトに適切な数値の接尾辞を付けておいた方がいいでしょう。C#はビット単位のオペランドを演算子にプロモートするためint、結果がaに収まることが保証されている場合でもbyte、問題はそれほど重要ではありません。
-supercat

'0'の定数名がゼロであるかどうかはわかりませんが、コードが読みやすくなる場合があります。たとえば、この定数がゼロの場合-「ROOT_TYPE_ID = 0」は、if(id!= ROOT_TYPE_ID){..}
Tech Junkie

6

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

ここにリストされていない可能性のある理由は、多くの品質ツールがマジックナンバーの使用にフラグを立てているためです。特にコード内の複数の場所で重複している場合、後で変更できるようにマジック番号を明確に表示せずにアルゴリズムにスローすることは、しばしば悪い習慣です。

そのため、これらのツールはそのような問題にフラグを立てることには適していますが、これらの値が無害で静的である可能性が高い状況、または初期化値である可能性が高い状況では、多くの場合検知を生成します。

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

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

パフォーマンスについて

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


5

Zeroタイプであると明示的に定義するので、これは理にかなっているかもしれませんfloat

少なくともCおよびC ++では、値0.0はtype ですがdouble、同等の値はfloatです0.0f。だから、xあなたが比較することを前提とすることも、常にfloat格言

x > 0.0

実際に問題につながる可能性のあるタイプに一致するxように昇格します(特に等価テストを使用)。変換なしの比較はもちろんdouble0.0

x > 0.0f

と同じです

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

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


1

まず、ここでゼロはとしてfloatではなくとして定義されintます。もちろん、これは比較に何の影響も与えませんが、この定数が使用される他のケースでは、違いが生じるかもしれません。

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


1

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

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


0

[is]これは、実際には以下よりも効率的であり、読み取り可能または保守可能です。

if (x > 0.0) {..}

ジェネリック(つまり、タイプ固有ではない)コードを書いている場合は、非常に可能性が高いです。zero()関数は、任意の代数タイプ、またはグループWRTの添加である任意のタイプに適用することができます。整数、浮動小数点値、変数が線形空間内の関数である場合は関数(たとえば、xはz-> a_x *の線形関数です) z + b_x)を使用し、基礎となる型であるzero()aおよびbを関数に提供しますzero()

そのため、たとえば、C ++(a zero()はあまり一般的ではありませんが)、またはジュリア、そしておそらく他の言語でこのようなコードを期待します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.