使い捨て電卓
世の中には使い捨てライター、使い捨てカメラに至るまで、「使い捨て何とか」がたくさんあります。そこで、rpnで使い捨て電卓を作ってみましょう。ここでいう使い捨てとは、電卓で計算する式が今回限りで、次に計算式を再利用することはないだろうという意味です。
崖の上から小石を水平に打ち出したとしましょう。この場合、打ち出したt秒後の崖からの落下距離を求めてみることにします。垂直方向の移動距離は、物体の自由落下に置き換えることができるので、自由落下のt秒後の距離を求めればよいわけです。これは距離=重力定数の1/2×経過秒数の2乗で計算できます。
o
o +----
o | 崖 | 1
o | | 落下距離 = --- × 重力定数 × 落下時間
o | | 2 (9.8) (t秒)
o | v
この公式を使って1.5秒後、3秒後、10秒後の落下距離を求めると、以下のようにrpn式を3回計算することになります。
11.025
>rpn 3 . * 9.8 2 / *
44.1
>rpn 10 . * 9.8 2 / *
490
毎回同じrpn式を入力するのは面倒ですよね。変わるのは秒数だけで式はまったく同じなのに入力するキータイプは多いし、打ち間違いも心配です。そこで、あたかも使い捨て電卓のように、公式の部分だけを切り離して計算させれば楽そうです。
使い捨ての数式
rpnには「-t」というオプションがあります。-tオプションは標準入力からのrpn式(データ含む)に-t以降のrpn式を連結して処理するオプションです。百聞は一見にしかずです。落下物のt秒後の距離を求めるには以下のようにします。
1.5 <--- 1.5を入力
11.025 ---> 11.025が結果
3 <--- 3を入力
44.1 ---> 44.1が結果
10 <--- 10を入力
490 ---> 490が結果
^Z ---> ^Zで終了
(Ctrlキーを押しながらZキーを押す(最後にエンターキー))
この「-t . * 9.8 2 / *」が使い捨て電卓の部分です。ここを変えればあなただけの特注の電卓ができます。あまり複雑な数式は無理ですが、日常使うようなほとんどの計算はできるでしょう。
一応、上記rpnの動作を詳しく見てみましょう。
① ②
①の-tがオプション、②の「. * 9.8 2 / *」が-tで連結するrpn式です。キーボードから入力された「1.5」に対して②が毎回連結されます。つまり以下のようになります。
1.5 . * 9.8 2 / *
入力した「3」 と -tの「. * 9.8 2 / *」が連結されて…
3 . * 9.8 2 / *
この繰り返しになります。とりあえず、数式だけを-tで作っておいて、計算に必要な数値は随時、入力するスタイルですね。
データをリダイレクトで入力
-tオプションはキーボードからの入力だけに対応しているわけではありません。例えば、以下のように0.1から1.0までが格納されたファイルがあるとします。名前はdata.txtとしましょう。
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
このデータを自由落下開始からの秒数だと考えると、落下1.0秒までの0.1秒刻みでの秒数ということになります。それぞれの数値に対して落下距離を求めるとします。電卓でやっていると大変ですね。しかし、rpnなら簡単です。
0.049
0.196
0.441
0.784
1.225
1.764
2.401
3.136
3.969
4.9
一つずつrpn式を打たなくても、一気に計算できました。
rpnの動きを以下の図で説明すると、まずdata.txtのデータがリダイレクトでrpnに渡されて落下距離の計算が行われます。計算結果のデータはそのまま画面に表示されるという仕組みです。
| | (data.txtから取り出して…)
v |
>rpn -t . * 9.8 2 / * <data.txt
|
+-----------------------> (画面へ表示)
(落下距離を計算して…)
ちなみに以下のrpn式でも同じ結果になります。
0.049
0.196
0.441
0.784
1.225
1.764
2.401
3.136
3.969
4.9
今度はdata.txtの内容をtypeコマンドがそのままリダイレクトして、rpnに渡します。渡されたデータからrpnは落下距離を計算して、画面に表示するという仕組みです。
+-----------------+
| | (落下距離を計算して…)
| v
>type data.txt | rpn -t . * 9.8 2 / *
|
+------------> (画面へ表示)
さて、落下経過時間の0.1秒から1.0秒まで計算しましたが、結果が画面にだけ流れて消えていってしまうのはもったいないですね。計算結果をファイルに格納できれば、データとして再利用できそうです。
これで計算結果がtmpファイルに格納されます。これもリダイレクトの仕組みを使っているので、以下の図で説明しましょう。
| | (data.txtから取り出して…)
v |
>rpn -t . * 9.8 2 / * <data.txt >tmp
| ^
| | (ファイルへ格納)
+-----------------------+
(落下距離を計算して…)
data.txtのデータがリダイレクトでrpnに渡されて落下距離の計算が行われるところまでは同じですが、計算結果のデータが画面ではなく、tmpファイルにリダイレクトされています。これで計算結果がtmpファイルに格納されたわけです。確認のためにtmpファイルをtypeコマンドで表示してみましょう。
0.049
0.196
0.441
0.784
1.225
1.764
2.401
3.136
3.969
4.9
きちんとファイルに格納されていますね。
リダイレクトを使ったrpnの計算スタイルはいかがでしたでしょうか。rpnが目指してきた使い方の一つがあらわれていると思います。rpnは少しとっつきにくい面もありますが、慣れればあなたのちょっとした右腕になりますよ(きっと)。
落下の放物線を描く
最後にこのデータを元にして、落下の様子をグラフで描いてみましょう。落下しているイメージを出すために距離をマイナスにしてみます。演算記号の「m」を使うことで、数値の正負を反転させることができます。使い方は以下のように簡単です。
-1 1
正負の符号が反転しているのが分かります。これは-1を掛けることと同じです。従って、tmpファイルに適用すれば全ての数値をマイナスの値にすることができます。
ちなみに、符号を操作する演算記号には「a」もあります。数値を絶対値変換するので、与えられた数値は全てプラスになります。従って、「a m」の組み合わせで、どんな数値も必ずマイナスになります。以下の例を参照ください。
1 1 -1 -1
さて、落下の様子を描くには垂直方向の落下距離と同時に水平方向の飛行距離が必要です。水平方向は空気抵抗がないと考えて等速度と考えましょう。軽く水平方向に蹴飛ばした小石の速さを時速10キロくらい(2.8m/s)と考えて、以下のrpn式を実行してみます。
+--*---*------------------------------->
|o * 3
| * x
| *
|
| *
|
| *
|
| *
|
| *
|
|
| *
|-5
うまく落下の放物線が描かれました。でも、ちょっと複雑なrpnの式ですね。特に「@x .28 + #x」のあたりが難しいかもしれませんが、後の連続番号の章に詳しく説明してあるので、そこまで読めばすぐに理解できるようになります。