なぜビット演算子は比較よりも優先度が低いのですか?


63

理由を説明してもらえますか、なぜ最も一般的な言語の束(下記の注を参照)で比較演算子(==、!=、<、>、<=、> =)がビットごとの演算子(&、|、^ 、〜)?

この優先順位が自然な使用法に出会ったことはないと思います。それは常に次のようなものです:

  if( (x & MASK) == CORRECT ) ...   // Chosen bits are in correct setting, rest unimportant

  if( (x ^ x_prev) == SET )      // only, and exactly SET bit changed

  if( (x & REQUIRED) < REQUIRED )   // Not all conditions satisfied

私が使用する場合:

  flags = ( x == 6 | 2 );     // set bit 0 when x is 6, bit 1 always.

存在しないに近い。

言語設計者がこのような演算子の優先順位を決定する動機は何でしたか?


たとえば、上位12言語のSQLを除くすべての言語は、langpop.comのプログラミング言語の人気リスト(C、Java、C ++、PHP、JavaScript、Python、C#、Perl、SQL、Ruby、Shell、Visual Basic)に類似しています。


16
Cの元のデザインの誤り
ラチェットフリーク

7
@gnat、その苦情のポイントは何ですか?OPは「すべて」ではなく、「最も人気のある言語の束」とは言いませんでした。そして、大多数はこの順序に従います。この表では、上位12(SQL)の1つだけがそうではありません:langpop.com

3
@ dan1111のポイントは、当然、回答者が質問をよりよく理解し、より良い回答を提供できるようにすることです。ご存知のように、これは推測ゲームの場所ではありません-または、ツアーページにあるように、「ディスカッションフォーラムではありません。チャットはありません。」
-gnat

7
@gnat、ゲームを推測することについてのあなたの懸念に同意しますが、ほとんどすべての人気のある言語が記述された動作を示すとき、これは資格があるとは思いません。

5
@Dunk:一般的な "by hunch"アプローチは[arithmetics] [logic operator] [arithmetics]です。ほとんどのプログラマーは、混乱のような括弧を作成しませんif(((x+getLowX()) < getMinX) || ((x-getHighX())>getMaxX())))-ほとんどが論理よりも算術のif( ( x + getLowX() < getMinX ) || ( x - getHighX() > getMaxX() )) 優先順位を仮定し、+上記の優先順位を仮定して記述し<ます。これでif( x ^ getMask() != PATTERN ) 、XORは算術演算子であり、直感的に同じように動作するはずです。解釈されたという事実if( x ^ ( getMask() != PATTERN ) )は完全に直感に反します。
SF。

回答:


72

言語はそれをCからコピーしました。C については、デニスリッチーが最初に、B(およびおそらく初期のC)&に、文脈に応じてビット単位または論理的な1 つの形式しかなかったと説明します。後で、各関数に演算子が追加さ&れました。ビット単位の演算子と論理演算子の演算子です&&。その後、彼は続けます

彼らの遅々とした紹介は、Cの優先規則の不正確さを説明しています。Bに1つ書く

if (a == b & c) ...

a等しくbcゼロ以外であるかどうかを確認します。そのような条件式では、より&優先順位が低い方が良いです==。BからCに変換する場合、そのようなステートメントで置換&する必要があり&&ます。変換の苦痛を少なくするために、&演算子の優先順位をに対して同じに保ち、==単に優先順位を&&からわずかに分割することにしました&。今日、の相対的優先順位を移動させることが好ましいであったであろうと思われる&==、それによって共通のCのイディオムを簡素化:別の値に対してマスクされた値をテストするために、一方が書かなければなりません

if ((a & mask) == b) ...

内側の括弧は必要ですが、簡単に忘れられます。


1
c=2Orがa==b結果になったのに失敗しなかったら失敗~0しません1か?
SF。

そう、a == bは0または1を返します。cm.bell-labs.com/ cm / cs / who / dmr / kbman.htmlを参照してください。
AProgrammer

回答の参照を確認し、前のテキストを読んでください。
シャヒーン

1
@MasonWheeler:特に組み込みシステムでは、関数のようなマクロを使用することが必要になる場合があります(場合によっては、インライン関数よりも桁違いに優れたパフォーマンスを提供でき、一部の組み込みシステムでは重要になる場合があります)。そのようなマクロ内で変数を宣言することはできません。マクロ内でグローバル変数を使用しても動作する可能性がありますが、本当に厄介なようです。
supercat 14

6
@MasonWheeler:数量1000で0.50ドルでRaspberry PiまたはArduinoを見つけることができますか?
supercat 14

7

ビットごとの演算子は、概念的にも外観的にも論理演算子に関連しているため、優先順位表で互いに近い理由をおそらく説明しています。おそらく、それ&よりも高いが==、それより&&低いと混乱するだろうと主張することさえでき==ます。

優先順位の前例(!)が設定されたら、一貫性を保つために他の言語がそれに従うのがおそらく良いでしょう。

ただし、これは最適ではないことに同意する傾向があります。実際の使用では、ビット演算子は論理演算子よりも数学演算子に似ており、数学演算子を優先してグループ化するとよいでしょう。

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