hirax.net::Keywords::「エクセル」のブログ



2014-08-22[n年前へ]

Excelで”-1^2″の計算結果が1で、”0-1^2″は-1になるヒミツ!? 

 Excelで”-1^2″の計算結果が1で、”0-1^2″は-1になるヒミツ!?を書きました。この話題、遙か昔から定番ですが、とても面白いと思います。

 このようなExcelの演算子解釈ルール(優先順位ルール)は、どのようにして生まれたのでしょう?「それは、きっとExcelに先行して発売されていた表計算ソフトのVisicalcやLotus 1-2-3にならったに違いない!」と言われることも多いのですが、残念ながらそうではありません。Visicalcの演算子解釈順は、単純に左から右へと並ぶ”並び順”で解釈されますし、Lotus 1-2-3は…

2017-12-05[n年前へ]

Microsoft Excelで "=-1^2" が "-1"ではなくて"1"になる「理由」 

 Microsoft Excelで "=-1^2" が "-1"ではなくて"1"になるのが「なぜだろう?」というtweetを興味深く読み、そこから辿り着いた20年前のメーリングリスト記事が面白かったので、簡単なメモ書きをしてみます。メモ書きなので、面白い記事へのポインタと(その記事に対する)わずかな感想を書いただけの日記記事です。

 まず、この計算順にまつわる問題を考える時には、" Warning: Excel Performs Negation Before Exponentiation"のタイトルにもなっているように、Excelという一種のプログラミング環境上での、"negation"と"subtraction"という異なる2演算子の計算順序の違いを区別する必要があります。つまり、

=-A1^2
は"=(-A1)^2"と計算されるけれど、
=1-A1^2
は"=1-(A1^2)"と計算されるというように、前者の"negation"と後者の"subtraction"が異なる演算子として区別され・違う演算順序が適用されるという話です。

 次に、20世紀最後の年、つまり西暦2000年1月13日の20:18:46にDoctor Petersonがメールで書いている文面がとても参考になります。それは、"negation"のような単項演算子は”exponent”のような二項演算子に優先して演算されるものだったから、それをただ踏襲すると、こんな計算順序になるよね、というものです。「Lotus 1-2-3との互換性を重視した」わけではないけれど、プログラミング言語の過去経緯を踏まえて考える話だよね、というものです。

 そして何よりも、西暦2005年の12月16日にErikが書いているように、Windowsのメモ帳で "msgbox -2^2"と書いてから、そのファイルをtest.vbsという名前で保存して、もしもダブルクリックしたならば、(マイナス4ではなくて)"4"という答えが書かれたメッセージボックスを私たちは目にするよね。この例でもわかるように、エクセルの「ダメな話」として眺めるのではなくて、コンピューター科学の「興味深い話」として眺めるべき話じゃないか?というコメントが、とても参考になると思います。

So I think this isn't bad math on Excel's part, but good computer science.

2020-01-22[n年前へ]

「エクセルの計算順序」から「コンピュータの歴史」を感じよう! 

-2020年になった今、1950-1980の時代を振り返る-

-1^2の計算結果は-1になる!?「エクセルの計算順序」の謎

 オフィス作業の多くがMicrosoft Excel(エクセル)上で行うのが当たり前となっています。そのエクセルでシートを開き、”= 0 - 1^2”, “= -1^2 + 0”という2式をセルに入力すると、どんな計算結果が出力されるでしょうか?

「どちらも-1になるはず」と答える人が多いかもしれませんが、実際に式をセルに入力すると、”=0 - 1^2→ -1”, “=-1^2+0→1”という結果になります(図1(a))。だからといって、「エクセルの計算バグ!?」と考えてはいけません。なぜなら、これは伝統正しいエクセルの仕様だからです。

同じ“-”でも二項演算子の”-”と単項演算子の”-”がある?

「どちらも-1になるはず」という答は、2式をそれぞれ0 –(1^2)と-(1^2)+0という順番に暗算から得られたはずです。…けれど、エクセルが行う計算順は、それとは違う0 –( 1^2)と(-1)^2+0という順番です。その結果、 -1と1という計算結果をエクセルは得るのです。

「減算よりべき乗の演算の方が優先されるべきだから、エクセルの計算順はやはりおかしくない?」と思う人もいるかもしれません。しかし、エクセルも、2つの値間でべき乗計算を行う”^”は、減算を行う“-”より優先する仕様になっています。

 この2式には、”-” ”^” ”+”という演算子が登場します。そのうちの、”^”と”+”についてはすべて、左右の2値を使い演算を行う2項演算子です。ところが、”-”については、”= 0 - 1^2”では(被演算子が左右にある)2項演算子ですが、“= -1^2 + 0”については、(被演算子が左右の片方にしかない)演算で使う値が一個の単項演算子(Unary operator)として、エクセルの計算が行われます(図1(b))。

“= -1^2 + 0”の”-”は、”-”の右側にある1を符号反転させる演算子で、エクセルが採用する演算子優先順では、単項演算子は二項演算子に優先します(図1(c))。その結果として、-1^2+0は (-1)^2+0 として計算されて、1という値が出力されるのです。

コンピュータを広めた表計算ソフトが生まれた時代の計算順を調査しよう!

エクセルの演算順序が、一般的な代数式の計算順序と異なる仕様になった理由はわかりません。「エクセルが開発された当時、標準的に使われていたLotus 1-2-3との互換性を考えたのではないか?」とも思いたくなりますが、そうでもありません。

 なぜなら、Lotus 1-2-3では、エクセルと異なる-1^2=1という計算結果になるからです。また、1985年発売のエクセルの開発チームは、Lotus 1-2-3(1983年発売) に先行して1982年発売のMultiPlanも開発しましたが、Multiplanでもやはり-1^2=-1と計算していたからです。

 エクセルやMultiplanが発売当時を調べてみると、面白いことがわかります。表計算ソフトという形態を作り出したVisiCalcも、当時の表計算ソフトの用途と重なるところも多かったデータベースソフトdBaseでも、ビジネスプログラミング言語のCOBOLも、多くのソフトでエクセルと同じ演算結果を出力します(図2、図3)。  そんな時代背景を踏まえれば、エクセルが「単項演算子―は2項演算子^に優先する」という仕様にしたということも、いたって自然にも思えてきます。

セル間の計算順序には「2つの方法」が使われている

 「セル間の演算を簡単にできる」のが、今ではエクセルに代表される表計算ソフトウェアです。だから、エクセル等が計算を行う際には、セル内の演算順だけでなく、セル間の計算順序もきちんと決まっていて、エクセルでは、2つの異なるセル間の計算方法が使われています。

「依存関係ごとに、値が定まるものから先に」の計算順

通常使われているセル間の計算順は、「セル間の依存関係を(ツリー構造で)辿り、値が定まっている“源流“から計算を順に行っていく」というものです。たとえば、セルB2に”=10-B3”、そしてセルB3に”6”という文字が入力されていたら、まずは「セルB2の前に、セルB3を定義する」という依存関係を持つグループの中で順番を生成した上で、セルB3を表す変数に値6を設定し、そしてB3で10-6という演算を行って、結果の4を格納するのです。もしも、ユーザーがどこかのセルを書き換えた時には、そのセルが属する依存関係のグループ内のみで、上流から下流に向かって計算が行われます。

アルファベット順+Zの法則(左→右、上→下)の計算順

もうひとつのセル間計算順は、「通常の方法が使えない場合」に使われます。具体的には、自己参照(循環参照)が行われている場合、言い換えれば「依存関係を辿っていくと、いつの間にか自分に辿り着いてしまい、無限ループに陥る場合」に使われます。計算をするのに、自分(自セル)自身の値を入力(右辺値)として使う状況があるの?と感じられるかもしれません。けれど、方程式を解く必要がある場合など、自己を参照するような数式に対する計算ができると便利なことも多いのです。

 たとえば、x ==(2 -3 y) / 4, y == (5 – 6 x) / 7という一次連立方程式を解きたい場合、セルB1とB2をxと yだとした上で、それぞれに =(2 -3*B2)/4と =(5 - 6*B1)/7という式を入れてみます。すると、「循環参照が行われています・・・」という警告が出るので、設定を「反復計算を使う(計算回数はとりあえず100)」と変えて、反復計算を実行させる(F9を押す)と、x(B1)=-0.1, y(B2)=0.8と連立方程式の計算結果が求まります。

 反復計算を行う場合には、循環参照が行われている部分に対し、アルファベット順で前方の