Go to the first, previous, next, last section, table of contents.


RPN(逆ポーランド)方式とスタック

Calc は普通、RPN notation(逆ポーランド記法)を用います。 ヒューレット・パッカードの電卓や、 FORTH, PostScript を使ったことのある人はご存じでしょう。 (RPN は Reverse Polish Notation の略号で、 ポーランドの数学者 Jan Lukasiewicz にちなんでこう呼ばれています。)

スタックの基礎

逆ポーランド式計算機の中心的役割を果たすのが スタック(stack)です。 計算機のスタックはお皿のスタックに似ています。 新しいお皿(数)はスタックの top に乗せられ、 また取るときは top からのみ取ることができます。

訳注: 大きな食堂では、お皿を取ったり乗せたりすると、 バネの力でちょうどお皿一枚分の厚みだけ底が上下する設備があるが、 これが Push Down Stack らしい。 こうすると、お皿を乗せたり取ったりする場所「top」が 常に同じ位置に保たれる。 逆ポーランド式計算機のスタックも、ちょうどこのように作られており、 お皿を乗せて全体が一枚分下がることを「push」、 お皿を取って全体が一枚分持ち上がることを「pop」と呼ぶ。 ちなみに逆ポーランド方式では見かけ上、上と下が逆に表示される。 すなわち一番下が先頭(top)である。

2+3 というような計算において、2 とか 3 とかは オペランド(operands) と呼ばれ、 そして +オペレーター(operator) と呼ばれます。 逆ポーランド式計算機においては常に、オペランド群を先に、次に オペレーターを入力します。数が入力されるたびに、Calc はそれをスタック の top に追加というか push します。この場合の + のような演算子 キーが押されると、Calc はスタックから必要な数(この場合は 2 と 3 の2個)の オペランドを pop し、演算結果をスタックに push して答えます。

従って逆ポーランド式計算機において 2 と 3 の和を求めるには次のようにタイ プします: 2 RET 3 RET +。(RET キーすなわちリター ンは HP 電卓の ENTER キーに該当します。) さあやってみましょう。 M-# c と打って Calc ウインドウに入りましょう(チュートリアルウイン ドウに戻るには、もう一度 M-# c と打つか M-# o と打ちます)。 キーストロークの最初の4つ 2 RET 3 RET は、数値 2 と 3 をスタック top に「push」します。+ キーはスタック top から2つの数 値を「pop」し、和を求め、そして演算結果(5)をスタック top に push します。 この計算を行うキーストロークのそれぞれの段階で、スタックがどう表示される かを以下に示します。

    .          1:  2          2:  2          1:  5              .
                   .          1:  3              .
                                  .

  M-# c          2 RET          3 RET            +             DEL

`.' 記号はスタック top を示すマーカーです。 スタック top がスタックウインドウの一番下に表示されることに注意してください。 これは反対のように感じられるかもしれませんが、 普通はこのほうが気が散りにくいのが判ります。

訳注: `.' 記号のひとつ上が top の項らしい。

`1:'`2:' などの左にある数字は スタックレベル番号(stack level numbers) です。 従来の逆ポーランド式電卓には、x, y, z, t と呼ばれる常に 4つのスタックレベルがありました。 それに対し Calc のスタックは好きなだけいくらでも増えるので、 名前ではなく数字で示すようになっています。いくつかのスタック操作コマンドは、 どのスタックに対する操作か明示するための数値引数を受付けるようになっています。 + のような普通のコマンドは、 常に top からいくつかのスタックに働くようになっています。

訳注: スタックレベル1の内容を第1項、レベル2を第2項として考えると 判りやすい場合がある。

スタックバッファは単なる Emacs のバッファですから、 普通の Emacs コマンドを使ってスタックバッファ内を自由に動き回ることができます。 しかしカーソルが何処にあろうと(たとえ `.' マーカーをビューの外に スクロールアウトしても)、ほとんどの Calc コマンドは常に、 カーソルをスタックレベル 1 に戻してから動作します。 一時的に + のようなコマンドからいくつかの数を「隠して」、 `.' マーカーをスタック上方に動かすことは可能です。 これは stack truncation(スタック切断)と呼ばれますが、 このチュートリアルでは触れません。 興味のある人はTruncating the Stack 参照 。

キーストローク 2 RET 3 RET + において、実は2番目の RET は必要ありません。それは数を入力しているとき続いてオペレーター 名や非数値キーがタイプされたなら、計算機は求められたコマンドを実行する前 にまず自動的にその番号を入力するからです。従って 2 RET 3 + がちゃんと作動するでしょう。

このチュートリアルの例ではしばしば RET を省略します。たとえ 、例示 されたスタックディスプレイが RET を押さなければ見られない場合でさ えも、です。:

1:  2          2:  2          1:  5
    .          1:  3              .
                   .

  2 RET            3              +

ここで、3 を押したときに本当はスタックには `1: 2' と、ミニバッ ファには `Calc: 3' と表示されるでしょう。この状況で、図が示すとお りのスタックを見るためには、余分に RET を押せば見えます。

(*) 練習問題 1. (このチュートリアルはいろいろなところ で練習問題を出します。気が向いたらやってみなさい。練習問題の解答はチュー トリアル章の終わりに位置しています。それぞれの練習問題が対応する解答に相 互参照を持っています。もし Emacs Info システムで読んでいるなら、解答を見 るためには f と問題番号を押し、元の位置に戻るためには文字 l を押してください。)

(*) 最初の練習問題です:キーストローク 1 RET 2 RET 3 RET 4 + * - は何を実行するでしょうか?(`*' は乗算の記号です。) まず机上で考えて、次に Calc を操作して正しいか確認してください。 逆ポーランド 練習問題 1 解答「1 RET 2 RET 3 RET 4 + * - 参照 . (*)

(*) 練習問題 2. スタックを使って 2*4 + 7*9.5 + 5/4 を計算しなさい。 逆ポーランド 練習問題 2 解答「2*4 + 7*9.5 + 5/4 参照 . (*)

スタック操作コマンド群

DELキーはキーボードによってはバックスペースと呼ばれます。普通 Emacs を使っているとき、単純なタイプミスを直すときに使うキーのことです。 DEL キーはスタックを pop して、top の値を破棄します。 (もし後で必要になったなら、「トレイル」からその値を取り戻すことができます。) このチュートリアルの多くの部分で、 新しい例題の初めに前の例題の結果を消去するために、 あなたが DEL を使ったと想定しています。 例外的に、 古い結果を削除するために DEL を使うことが本当に重要な箇所がいくつかありますが、 その場合はテキストに明記してあります。

((DEL キーを使わないで)スタックにいろいろ貯めても別に害は無いのですが、 ただし表示形式を変更するコマンドを使うときは、 そのような大きなスタックを再表示するのに時間がかかってしまうのです。)

-キーもまたオペレーター (スタック top の2つの要素を引き算します)なのですが、 それでは負の数はどう入力したら良いでしょう? Calc ではマイナス記号のようにふるまう _ (アンダースコア)キーを使います。 - キーが引き算をしようとするため、 -5 RET と打っても駄目ですが、 _5 RET とすればうまくいきます。

n を押す方法もあって、これは「サインチェンジ」という意味です。スタッ ク top の(あるいは入力中の)数を正から負へ(あるいはその逆へ)変化させます。 たとえば 5 n RET とします。

数を入力していないとき RET を押すと、スタック top の数を複製します。 この計算を見てみましょう:

1:  3          2:  3          1:  9          2:  9          1:  81
    .          1:  3              .          1:  9              .
                   .                             .

  3 RET           RET             *             RET             *

(もちろん、3 の 4乗を計算するもっと簡単な方法は 3 RET 4 ^ で す。)

スペースバー(ここでは SPC と示します)は、RET と同じ機能を持 ちます。上の例題に RET が3回出てきますが、全部 SPC で置き換 えても同じ結果になります。

もう1つのスタック操作キーが TAB です。これはスタック top の2つの内 容を交換します。あなたは今、5を得るために、2 RET 3 + を計算 したとします。ところがその後で、実際には計算したかったのは 20 / (2+3)であったことに気付きました。

1:  5          2:  5          2:  20         1:  4
    .          1:  20         1:  5              .
                   .              .

 2 RET 3 +         20            TAB             /

あらかじめ見通しがあれば、計算はこのようにできたでしょう:

1:  20         2:  20         3:  20         2:  20         1:  4
    .          1:  2          2:  2          1:  5              .
                   .          1:  3              .
                                  .

  20 RET         2 RET            3              +              /

関連するスタック操作コマンドに M-TAB があります(META を(押さえたまま)保持して、そして TAB をタイプしてください) (訳注: MS-Windows において Alt-TAB はタスク切替キーなので、 ここは ESC TAB で代用すべき)。 それは、 スタック top の3つの要素を上向きに回転させて、レベル3 のオブジェクトを top に持って来ます。

1:  10         2:  10         3:  10         3:  20         3:  30
    .          1:  20         2:  20         2:  30         2:  10
                   .          1:  30         1:  10         1:  20
                                  .              .              .

  10 RET         20 RET         30 RET         M-TAB          M-TAB
                                             (ESC TAB)      (ESC TAB)

(*) 練習問題 3. 数 10, 20, 30 がスタックにあるとしましょ う。スタックの残りに影響を与えないで、レベル2 の数に 1 を加えるにはどう すればよいか答えなさい。同じくレベル3 の数に 1 を加える場合も答えなさい。 逆ポーランド 練習問題 3 解答「レベル2 とレベル3 の操作」 参照 . (*)

+, -, *, /, ^ のような二項演算子はスタックから 2つの引数を pop して、そして計算結果を push します。 また nQ (ルート)のような単項演算子はひとつの数を pop して、 そして結果を push します。 単にスタック top の要素に作用すると考えても良いでしょう。

1:  3          1:  9          2:  9          1:  25         1:  5
    .              .          1:  16             .              .
                                  .

  3 RET          RET *        4 RET RET *        +              Q

(大文字 Q は、シフトキーを押しながらの q を意味することに注 意してください。普通の、シフトしない q は Quit コマンドです。)

ここで我々は直角三角形の斜辺を決定するためにピタゴラスの定理を使いました。 実はそのために Calc は f h という組込みコマンドを持っているのですが、 ここではそのキーストロークを覚えていないとしましょう。 覚えていなくても M-x 表記法を用いてフルネームで入力することができます:

1:  3          2:  3          1:  5
    .          1:  4              .
                   .

  3 RET          4 RET      M-x calc-hypot

すべての計算コマンド群は `calc-' で始まります。いちいちこれをタイプ するのは骨が折れるので Calc には x キーが用意されていて、普通の Emacs M-x キーとほとんど同じですが、続けて `calc-' までタイプ してくれます。

1:  3          2:  3          1:  5
    .          1:  4              .
                   .

  3 RET          4 RET         x hypot

複素数, ベクトル, 不完全項

負の数の平方根をとるとどうなるでしょう?

1:  4          1:  -4         1:  (0, 2)
    .              .              .

  4 RET            n              Q

表記 (a, b) は複素数を意味します。複素数は伝統的には a + b i と書かれます。Calc はそのようにも表示できますが、 ここでは (a, b) 表記法を使うことにします。

もし複素数の振舞いを知らないなら、この機能は無視してもかまいません。複素 数を持たない計算機でエラーが出るような演算をすると複素数が発生します。 (例えば負の数のルートや log を取ると複素数の結果が出ます。)

複素数はご覧の表記法によって入力できます。(, ,, ) キーは「未完成の複素数」を完成させる部品として機能します。

1:  ( ...      2:  ( ...      1:  (2, ...    1:  (2, ...    1:  (2, 3)
    .          1:  2              .              3              .
                   .                             .

    (              2              ,              3              )

不完全項の部分を入力している最中にも計算することができます。た だし、不完全項は演算に参加することができません。

訳注: 数値など、数式のひとつの項になりうるものが「完全項」で、 複素数の部品など、項として未完成なのが「不完全項」らしい。

1:  ( ...      2:  ( ...      3:  ( ...      1:  ( ...      1:  ( ...
    .          1:  2          2:  2              5              5
                   .          1:  3              .              .
                                  .
                                                             (error)
    (             2 RET           3              +              +

不完全項に 5 を加えるのは意味をなしません。 そこで最後のコマンドはエラーメッセージを発生させて、スタックは元のままです。

不完全項は演算に参加することはできませんが、 正規のスタックコマンドで動き回らせることはできます。

2:  2          3:  2          3:  3          1:  ( ...      1:  (2, 3)
1:  3          2:  3          2:  ( ...          2              .
    .          1:  ( ...      1:  2              3
                   .              .              .

2 RET 3 RET        (            M-TAB          M-TAB            )
                              (ESC TAB)      (ESC TAB) 

ここで、, (コンマ)が使われる必要が無かったことに注目してください。 ) を押したとき、( から top までのすべてのスタック内容は集め られますから、実際コンマを使わねばならない理由は無いのです。それはあなた 次第です。

(*) 練習問題 4. 複素数 (2, 3) を入力するために、 友人ジョーは ( 2 , SPC 3 ) とタイプしました。どうなったでしょう? (ジョーはたった2つのキーストロークでミスを修正するうまい方法を考えましたが、 うまく行きませんでした。なぜか考えてみてください) 逆ポーランド 練習問題 4 解答「ジョーの複素数問題」 参照 . (*)

ベクトルは複素数と同様に入力されますが、カッコではなくカギカッコを使いま す。ベクトルはまた後で改めて紹介します。

接頭引数

どの Emacs コマンドも、事前に META-数値 の並びをタイプすることによっ て、接頭引数 を与えることができます。もし META が不便である なら、その代わり C-u のあとに必要な引数をタイプすることができます。 M-- M-3 M-5C-u - 3 5 のように、接頭引数は負数も取り 得ます。Calc コマンド群は接頭引数をいろいろな方法で使います。例えば、 + 演算子における接頭引数は、複数のスタック要素をいくつでも一気に加 算します:

1:  10         2:  10         3:  10         3:  10         1:  60
    .          1:  20         2:  20         2:  20             .
                   .          1:  30         1:  30
                                  .              .

  10 RET         20 RET         30 RET         C-u 3            +

RET のようなスタック操作コマンド群では、正の接頭引数は top から n個のスタック要素全てに同時に作用します。負の接頭引数はスタックレ ベル n の要素にのみ作用します。ゼロの接頭引数はスタック全体に作用 します。次の例では、top から2番目(スタックレベル 2)の要素をコピーします:

1:  10         2:  10         3:  10         3:  10         4:  10
    .          1:  20         2:  20         2:  20         3:  20
                   .          1:  30         1:  30         2:  30
                                  .              .          1:  20
                                                                .

  10 RET         20 RET         30 RET         C-u -2          RET

もうひとつ良く使う操作は M-0 DEL で、スタック全体をクリアします。 (M-0 という接頭引数が DEL にスタック全体に作用せよと指示します。)


Go to the first, previous, next, last section, table of contents.     利用度数