よく、小学生のころに、掛け算は足し算よりも先に計算するとか、そういう話題になったかと思います。
今回の記事は、そういうお話しです。
私の記憶では、小学校の算数において明確な順位付けをされていたのは、以下の通り。
括弧演算子がネスト(入れ子)されている場合は、もっとも内側から優先的に計算する。
掛け算や割り算は、足し算や引き算よりも先に行う。
※但し、分数の分母や分子に足し算や引き算がある場合、分母分子に見えない括弧演算子があるものと考える。
分数の分母や分子に分数が含まれる場合、割線の短いものから優先的に計算する。
これ以外は、左から右へ順番に計算する。
といったところだろうか。
続いて、中学生になると、無理数を学ぶようになるために、べき乗が登場する。
abc
テキストベースの環境では、a^b^cのように記述される。
実は、このべき乗にも例外的な優先順位が存在し、b^cを先に計算する。
では、実例を示してみましょう。
a=2, b=3, c=5として、
(a^b)^c=8^5=32768
a^(b^c)=2^243=14134776518227074636666380005943348126619871175004951664972849610340958208
ぜんぜん答えが変わってきてしまいますね。
また、前者の場合、
(a^b)^c=a^(b*c)
ということが出来るので、表記として左の表記の意味がなくなってしまうので、意味がないという意見があります。
では、私はなぜ、このような勘違いをしていたのだろうか。
それは、中学のころに、まったく授業を聞いていなかったから。
また、3段以上になるようなべき乗の計算をした記憶がないから。
続いて、プログラミング言語では、計算式における優先順位を明確にするため、括弧演算子を多様するから。
また、プログラミング言語では、言語ごとに仕様が異なっていてもなんら問題はなく、どれが正しいということではないから。
べき乗の二項演算子がある言語はFORTRANくらいしか知らなく、他はpower関数といったもので、否が応でも優先順位を明確に示さねばならないため。
ExcelでもPOWER()ワークシート関数だけではなく、^記号も使えるが、左から右に計算してしまう。
=2^3^5
を計算させると、
32768
となります。
これは、Excelという閉じられた世界では正しい(仕様)ということです。
そうなると、数学という閉じられた世界では、どちらかが正しい、もしくは未定義といった、数学的な見解を示さねばならない。
では、数学的にどちらが正しいのかを考えてみましょう。
^は二項演算子と呼びます。
二項演算には、可換なものと、非可換なものに分類されます。
四則演算の、+や×は可換な演算子、-や÷は非可換な演算子です。
^演算子は可換なのか、非可換なのか。
a≠bのとき、a^b≠b^aとなるので、^演算子は非可換ということになります。
ここを前提として、
a^b^c=(a^b)^c と考えると、
(a^b)^c=a^(b*c)=(a^c)^b=a^c^b
となり、可換となってしまい矛盾が生じます。
よって、
a^b^c = a^(b^c)
と定義するのが、数学的には正しい(妥当)となります。
二項演算子が出てきたので、単項演算子についても書いておきます。
単項演算子とは、+3、-2、5!、といったものです。
よく議論になるのが、
-3^2
これがいくつなのか。
0-3^2
と結果が同じなのか。
単項演算子は、二項演算子よりも優先順位は高いのです。
ですので、
-3^2=9
となり、-9ではありません。
また、
0-3^2=0-9=-9
となります。
ややこしいのが、単項演算子である符号演算子と加減算演算子が、全く同じ記号であることです。
では、ブログのようなテキストベースの環境下において、正しく認識してもらうには、明確に括弧演算子を使って示す他ないということになりますね。
プログラミング言語においては、仕様で定められているので、自分が求めている動きをしないといった場合、こういった優先順位の勘違いといったこともあるかと思われます。
そう言えば、つい最近ですが、atan2という関数において、JavascriptとExcelで順序が逆だということに気が付きました。
atan関数とは、数学的にいうところのarctan関数のことで、arctanとは、tanの逆関数のことです。
y=x・tanθ
というx-y平面の関数において、
tanθ=y/x
となり、逆関数で
arctan(y/x) = θ
のようになります。
ここで、プログラミング言語としてはどうなるのか。
一般的なプログラミング言語には∞という概念がありません。
xに0が入ると、0除算というようなエラーを出すものもあります。
また、yが限りなく大きかったり、xが限りなく0に近いような場合、θの誤差が出やすくなってしまいます。
また、arctan関数は、別にy/xのようにxとyを別々に入れるような作りにはなっておらず、
atan(n)
のように1つの変数ないし、値で事足りわけです。
そこで登場するのが、atan2関数です。
xとyのような2つの変数を入れることが可能なのです。
それで、どのように定義されているかというと、
Excelでは、
ATAN2(x, y)
Javascriptでは、
Math.atan2(y, x);
のようにx,yの順番が違ったりします。
これは、どっちが正しいとか正しくないとかではなくて、仕様の一言で片付けられてしまいますね。
ではでは
↧
演算の優先順位
↧