演算子の優先順位

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

演算子の優先順位とは、数学およびコンピュータプログラミングにおいて、数式のどの部分から先に計算すべきかを明確化する規則である。

例えば、数学や多くのコンピュータ言語では乗法は加法より先に行われる。2 + 3 × 4 という式の計算結果は14になる。( と )、{ と }、[ と ] といった括弧には計算順序の混乱を防ぐ独自の規則が適用され、例えば先の式は 2 + (3 × 4) とも書けるが、括弧がなくとも乗法が優先されるという規則だけで式の値は一意に定まる。

代数学的記法が導入された際、乗法が加法より優先されるようになった[1]。したがって、3 + 4 × 5 = 4 × 5 + 3 = 23 となる。冪乗が16世紀から17世紀に導入されたとき、加法と乗法より優先されるとされ、底の右肩に冪指数を記述するようになった。したがって 3 + 52 = 28 であり、3 × 52 = 75 となる。演算順序を変えたい場合、かつては括線英語版オーバーラインまたは下線)を使っていた。今日では括弧を使って、先に評価すべき式の部分を明示的に囲む。したがって、乗法の前に加法を行うなら (2 + 3) × 4 = 20 などとし、冪乗の前に加法を行うなら (3 + 5)2 = 64 などとする。

標準的な演算子の優先順位[編集]

ここで示している演算子の優先順位は、数学・科学・工学全般で通用しており、多くのプログラミング言語でも同様である[2]

  1. 括弧内の項
  2. 冪乗冪根
  3. 乗法除法
  4. 加法減法

これの意味するところは、例えばある数式の項の前後にそれぞれ異なる演算子があった場合、上記一覧の上の方(数字の若い方)にある演算子を先に適用すべきだということである。加法と乗法の交換および結合法則により、項の加算は任意の順序で可能であり、乗数も任意の順序で乗算可能だが、それらが混在している場合は標準の優先順位に従わなければならない。

除法を逆数による乗法として扱うことができ、減法を加法的逆元の加法として扱うことができる。すなわち、3/4 = 3 ÷ 4 = 3 • ¼ である。言い換えれば、3を4で割った商は、3と ¼ をかけた積と等しい。同様に 3 − 4 = 3 + (−4) であり、3と4の差は正の3と負の4の和と等しい。この理解により、 1 − 3 + 7 という式は1と負の3と7の和とみなすことができ、任意の順序で計算可能である。すなわち (1 − 3) + 7 = −2 + 7 = 5 と計算することもできるし、 (7 − 3) + 1 = 4 + 1 = 5 と計算することもできる。項の順序を入れ替える際、負号を常に3に付属させることが重要である。

平方根記号 √ は被開数(平方根を求める対象となっている数)をグループ化する記号を必要とする。通常使われるグループ化の記号は被開数の上にひかれる横線(括線英語版)である。他の一般的関数は曖昧さを防ぐために入力を括弧で囲むが、入力が単項式であれば括弧を省くこともある。例えば、sin x = sin(x) だが、sin x + y = sin(x) + y となる。なぜなら x + y が単項式でないためである。計算機では、一般に全ての関数の入力を括弧で囲む必要がある。

冪指数が積み重なっている場合、一番上の冪乗から計算する。

グループ化の記号は通常の演算子の優先順位を無効にすることができる。グループ化された部分は1つの式として扱うことができる。交換および分配法則を使えばグループ化記号を排除することができる。

[編集]

\sqrt{1+3}+5=\sqrt4+5=2+5=7\,

水平な線分(括線)はグループ化記号として機能する。

\frac{1+2}{3+4}+5=\frac37+5

読みやすくするため、通常の丸括弧 ( ) だけでなく、角括弧 [ ] や波括弧 { } をグループ化記号として使うことがある。例えば次のような式である。

[(1+2)-3]-(4-5) = [3-3]-(-1) = 1 \,

例外[編集]

単項演算子としてのマイナス記号(負号)の扱い方はいくつかある。普通に書いた場合、−32 は −(32) = −9 を意味するが[3]、数式を扱うアプリケーションやプログラミング言語(特に Microsoft Office Excelプログラミング言語bc)では単項演算子を二項演算子より優先しているためマイナス記号は冪乗より優先順位が高く、−32 は (−3)2 = 9 と解釈される[4]。誤解が生じる可能性がある場合、括弧を使って意味を強調するのが一般的である。

同様にスラッシュ記号 ('/') を数式で 1/2x のように使う際にも曖昧さがある。これを 1 ÷ 2 × x の意味で書いているなら、除算記号を分数を使った乗算で表現していると解釈でき、次のようになる。

1 \div 2 \times x = 1 \times \tfrac{1}{2} \times x = \tfrac{1}{2}x

すなわちこの解釈では、1/2x を 1/(2x) ではなく (1/2)x と等価とみなしていることになる。Wolfram AlphaTI-89電卓では、括弧付きでない暗黙の乗法、括弧付きの暗黙の乗法いずれも演算子を明示した乗法と同じ扱いをしている。例えば、2x/2x、2(x)/2(x)、2*x/2*x はいずれも x2 となる[5]。 しかし書籍などでは、演算子を使わない暗黙の乗法を除法より優先すると解釈している場合がほとんどであり、1/2x は (1/2)x ではなく 1/(2x) と解釈している。例えばフィジカル・レビュー誌の論文投稿要綱では、スラッシュで表される除法より乗法の優先順位が高いとしており[6]ランダウリフシッツの『理論物理学教程』やファインマンの教科書などでも同様の慣習が見られる[7]

一般に曖昧な解釈が可能な数式は避けることが推奨されており、可能ならスラッシュではなく分数の形で記述すべきであり、そうでなくとも括弧を使って曖昧な解釈ができない形にすべきである。

記憶術[編集]

欧米では、演算子の優先順位を覚えるための記憶術があるが、その頭字語を使った記憶術のせいで間違って覚えることがある。アメリカでは PEMDAS (Parentheses, Exponents, Multiplication, Division, Addition, Subtraction) という頭字語を使う。これを "Please Excuse My Dear Aunt Sally" という文で覚える(各単語の頭文字が所定の順序で並んでいる)。カナダでは BEDMAS、イギリスでは BIDMAS または BODMAS である。Bは Brackets、Iは Indices、Oは Orders を意味する。

これには乗法と除法、加法と減法に優先順位の上下関係があるかのような錯覚を与える欠点があり、そのように覚えてしまうと

10 - 3 + 2 \,

という式を9ではなく5と計算してしまう可能性がある。

そのためニュージーランドでは、PEMA と教えている場合もある。この場合除法と減法が入っておらず、それぞれ乗法と加法と優先順位が等しいことを別途教える。

特殊な例[編集]

階乗感嘆符で表され、その直前(左)にある項に適用される。括弧が関わらない限り、階乗は優先的に計算される。ただし、23! は (23)! = 8! = 40320 を意味するが、23! は 26 = 64 となる。

冪乗が積み重なっている場合、上から計算する。すなわち次のようになる。

 a^{b^c} = a^{(b^c)} \ne (a^b)^c \,

中黒を乗法の記号として使うこともあり、その場合は中黒より前の式全体と中黒より後の式全体の乗法を意味することがある[要出典]が、この記法は誤解されやすい。すなわち x + y • a + b は (x + y)(a + b) を意味することがあるが、この意味に解釈する場合後者の記法がより一般的である。

電卓[編集]

電卓は機種によって演算子の優先順位が異なる場合がある。もっとも、電卓は数式を評価しているのではなく、単に操作順が数式に類似しているに過ぎず、本質的には、計算機としての内部の計算モデルの違いによるものである。

多くのいわゆる普通の電卓は、入力された順に計算する。例えば、

1 + 2 \times 3 = 9 \;

となる。これに対し、たいていの「関数電卓」は、加減算中の乗除算について別に計算できるバッファを持っており、

1 + 2 \times 3 = 7 \;

となる。Microsoft Windowsに添付されているアプリの電卓も、「普通の電卓」と「関数電卓」のモードに応じて、同様に異なった動作をする。

なお以上で説明した「関数電卓」は、いわゆる「標準方式」と呼ばれるもので、近年の関数電卓には数式をそのまま入力して評価する方式のものもある。

冪乗を計算できる電卓の場合、冪乗の結合性英語版が左右どちらなのかは機種によって異なる。例えば、TI-92とTI-30XIIで a ^ b ^ c を計算した結果は異なる。

TI-92では冪乗は右結合性なので次のようになる。

a ^ b ^ c = a ^ (b ^ c) =  a^{(b^c)} = a^{b^c}

一方TI-30XIIでは左結合性なので次のようになる。

a ^ b ^ c = (a ^ b) ^ c =  (a^b)^c

また 1/2x のような式は、TI-82では 1/(2x) と解釈されるが、TI-83では (1/2)x と解釈される[8]

プログラミング言語[編集]

多くのプログラミング言語では、算術におけるそれと同じ優先順位である。しかし、中にはAPLSmalltalkのように演算子の優先順位を持たない言語もある(APLではなんでも右から左へと評価していく。Smalltalkでは、なんでも左から右へと評価していく)。なお、プログラミング言語における演算子には、優先順位より下位の規則として「結合性」がある。結合法則#プログラミング言語を参照。

C言語ビット演算論理演算の優先順位は比較演算より低い。比較結果をさらに論理演算することは通常よくあるので妥当な設計と言えるが、ビット演算の優先順位の低さは問題があり、しばしばうっかりバグの原因となる(このバグがうっかりされやすいのは真偽値型が無いためもある。近年はコンパイラの警告で発見される場合もある)。これは初期の言語仕様の変遷によりそうなってしまったもので、設計者は良くないものとは認識したが、その時点ですでに蓄積されていたソースコードを壊さないためにそのままにされた[9]。C言語の影響を受けた言語では、たとえばGoのようにいくつかの言語ではこれを修正したが、C++PerlPHPJavaJavaScriptなどの多くの言語はそのまま踏襲しており、それらで経験を積んだプログラマはこれに慣れていることが多い(Javaでは型エラーになることが多いため、バグは少しは救われる)。Cにおける演算子の優先順位は次の通りである。

1 ()   []   ->   .   関数呼出し演算子、配列要素、メンバへのアクセス
2  !   ~   -   +   *   &   sizeof   type cast   ++   --   ほとんどの単項演算子など
3 *   /   % 乗法、除法、剰余
4 +   - 加法、減法
5 <<   >> ビット単位のシフト
6 <   <=   >   >= 大小比較
7 ==   != 等価/非等価比較
8 & ビット単位のAND
9 ^ ビット単位の排他的OR
10 | ビット単位の通常のOR
11 && 論理AND
12 || 論理OR
13  ?:   =   +=   -=   *=   /=   %=   &=   |=   ^=   <<=   >>= 条件式と代入
14 , コンマ演算子

例:

  • !A + !B(!A) + (!B)
  • ++A + !B(++A) + (!B)
  • A + B * CA + (B * C)
  • A || B && CA || (B && C)
  • (A && B == C)(A && (B == C) )

ソフトウェア開発者が二項演算子の優先順位について持っている知識の精度は、それら演算子がソースコードに出現する頻度と密接に関係していることが示されている[10]

脚注[編集]

  1. ^ Ask Dr. Math”. Math Forum (2000年11月22日). 2012年3月5日閲覧。
  2. ^ Order of Operations Lessons”. Algebra.Help. 2012年3月5日閲覧。
  3. ^ [Allen R. Angel, Elementary Algebra for College Students 8/E; Chapter 1, Section 9, Objective 3]
  4. ^ Formula Returns Unexpected Positive Value”. Support.microsoft.com (2005年8月15日). 2012年3月5日閲覧。
  5. ^ 2x÷2x - Wolfram|Alpha”. Wolframalpha.com. 2014年8月2日閲覧。
  6. ^ Physical Review Style and Notation Guide”. American Physical Society. 2012年8月5日閲覧。
  7. ^ 例えば、『理論物理学教程』第1巻「力学」第3版には、hPz/2π (p. 22) という式があり、スラッシュを最後に評価するという意味で書かれている。
  8. ^ Implied Multiplication Versus Explicit Multiplication on TI Graphing Calculators”. Texas Instruments Incorporated (2011年1月16日). 2011年4月29日閲覧。
  9. ^ Dennis M. Ritchie: The Development of the C Language. In History of Programming Languages, 2nd ed., ACM Press 1996.
  10. ^ "Developer beliefs about binary operator precedence" Derek M. Jones, CVu 18(4):14–21

関連項目[編集]

外部リンク[編集]