Home > Software Tips > HP電卓
Last Update 2023.01.08
電卓というハードではあるけれど、HP電卓の使い方という意味ではソフトカテゴリーでいいのかなぁ~と...
携帯電話をAndroidスマートフォンに変えてから、インストールする関数電卓をあれこれ探してみた。
試してみたのは、
RealCalc Scientific Calculator
基本的な電卓機能は揃っているし、外見も良い。長押しでSHIFTになるのも良いのだが、HMS変換が見当たらない。自分の用途では、時間・角度を扱うものが結構多いので、このボタンがないのはちょっと不便。
この電卓は、settingsでRPNモードに出来る。今まで逆ポーランド記法というものがあって...というところまでは知っていたが、SHARPやCASIOのプログラム電卓を使っていて、興味半分で更に買うほど余裕もなかったし、身近に使っている人もいなかったので、実際に触ってみたことはなかった。
その点アプリなら切替をするだけなので、試しに切り替えてみたら面白い。これがきっかけでHMS変換を求めながらRPNの方へ脱線をしてしまった。
RpnCalc
名前のとおり、これは切り替えではなしにRPNだけの電卓。HMS変換はあるけれど、ボタンの配置がどうもしっくりこなかったため、一旦アンインストールした。
Droid48
ボタンが所狭しとあるのが、HP48を再現したこいつ。もはや電卓というレベルじゃない。
ここで一旦探すのは打ち切って、2つをしばらく使ってみることにした。
電卓アプリを色々試しているなかで、Android端末内の電卓は、Droid48一本になった。
この前ある計測をした時の話
A-1、A-2 B-1、B-2 C-1、C-2
この6点で測定をして、A-1とA-2の平均でAの値とし、BとCについても同様に計算した後、AとCの平均値とBを比較ということをした。
※AとCを直線で結んだものとBとのずれ、梁のたわみのようなものが出てくることになる。
(A-1) (A-2) + 2 / ; これでAが求まる。 (C-1) (C-2) + 2 / ; スタックが一つ上がり、Cが求まる。 + 2 / ; Level1とLevel2のスタックの値の平均を取る。 (B-1) (B-2) + 2 / ; スタックが一つ上がり、Bが求まる。 - ; AとCの平均値とBとの差が出る。
当然、SHARPやCASIOの電卓でも出た値をメモしつつ、逐一変数へ格納すれば同じ事はできるし、複雑な式を書いてダイレクトに最後の答を得ることもできるし、対話式に値を入力させて答えを出すプログラムもできる。だが、HP電卓でやると、ちょこちょこと計算の途中経過を控えつつ、余計な変数操作や再入力をせずにできるのだ。
有効桁で丸めるのも、各計算後に(桁数)[RND]でOKだ。
マニュアルを眺めているとスタック操作のコマンドがたくさんあるが、結局どう動くのか良くわからない。自分なりに図にしてみた。
基本が左側の状態で、キー操作をすると右になる。
[ROT] / [UNROT]、[ROLL] / [ROLLD]は中央が操作前で、両側が操作後、左右で逆の効果になっている。
白いボックスは操作対象を指定するために置く数。数字は例。[Enter]しない状態でもOK。
50gやEmu48にはMOD関数があるのだが、35sや15cはどうなっているんだろう?と調べてみたら、35sはRmdrという機能があるらしい。
被除数、除数をスタックに積んで、[LS] [INTG] [3]とすると剰余が出る。これで解決。
15cにはないようだ。プログラムを書かないといけないか。
検索しつつプログラムを用意していると、被除数又は除数の符号が負の場合に云々という記述がいくつか見つかった。
MODに負の値を入れるって考えたことがなかった。いったいどういう値になるんだろう。
試しに50gでMODを使ってみた
10 -8 mod -6
マニュアルを見ると、
x mod y = x - y floor( x / y )
と定義されている。
floorは、引数を超えない最大の整数ということなので、負数の場合は単純に整数部を取り出すより1小さくなる。
数学的な定義はよくわからないけれど、「senzogawaのNな日々」の「負数の剰余」などを見ると、Cなどのプログラム言語の定義としては整数演算として
( a / b ) * b + ( a % b ) = a
が成立すれば良いらしく、( a / b )の答えをどうするかは処理系依存らしい。
丸めには、大きく3種類ある。
IPは単純に符号と整数部を取り出す*1ので0への丸めに相当するけれど、floorは負の無限大方向への丸めになる。
このため、負の値の時は答えが違うことになる。
例えば、10 / -8の場合実数値では-1.25になるが、整数値にしようとした場合、採用する丸めによって-1を返す場合と-2を返す場合があり得ることになる。
\ | ( a / b ) * b | a - ( a / b ) * b |
-1 | 8 | 2 |
-2 | 16 | -6 |
定義としてはどちらも正しいようだが、HP電卓を沢山使っている身としてはMODと同じ答えの方が頭も整理しやすいし、ExcelやWolfram|Alphaで試してみても-6になるので、これらと整合をとる方が都合が良さそうだ。
もし、他のプログラム言語で違う答えが返るようなら、その時対処することにする。
*1:対になるFPは符号と小数部
RNDについては、50g/48系と15c/35sで動作に違いがあるのでメモ
どれも四捨五入の動作なので、切り捨て・切り上げは別の操作が必要
RNDの対になる切り捨て。0への丸め。
桁数をスタックに指定してTRNCを実行すると、その桁数に丸められる。正の値(0から11)の場合小数点以下の桁数、負の値(-1から-11)の場合は符号を無視した有効桁数、12の場合は現在の表示形式
残りは整数を取り出す動作なので、任意の桁で実行したい場合は、事前と事後に10^nの乗除で桁をずらせる必要があるのかな。
自分の用途では、表引きをして一次補間で値を求める作業が結構ある。
しかも、同じキー値に対して複数個(状況により変化)の値を読み取る必要がある。
キー列 | 値A | 値B | 値C | … |
Key1 | a1 | b1 | c1 | … |
: | : | : | : | : |
キー値 | a? | b? | c? | … |
: | : | : | : | : |
Key2 | a2 | b2 | c2 | … |
従来のプログラム電卓でこれをしようとしたら、4つの値とキー値を順次打ち込んで一次補間計算をするという操作になるため、1組だけを対象とした単純なプログラムで左列、キー値を何度もキーインするか、ブレークするまでループをして補間値を求めるというプログラムを書く必要があった。
50gでどう書こうかと考えていたところ、行列計算の機能があることを思い出した。しかも与える行列はマトリクス・エディターで閲覧・編集が可能なので、入力値に誤りがあっても修正が容易だ。
さっそく、行列機能を使った補間計算を考えてみた。
《→ROW DROP SWAP DUP UNROT - DUP {1} GET DUP UNROT / 4 PICK 4 PICK {1} GET - * SWAP DROP +》
スタックに以下のようにデータを積んで実行する。
2:補間値を計算したい値(キー値) 1:補間元になる2行x列の行列
実行後はレベル1のスタックが補間後の1行x列の行列になる。
ちなみに、50gにしかないスタック操作があるので、Emu48のような48系では、「UNROT」は「ROT ROT」に、「PICK3」は「 3 PICK 」に修正が必要。
日付計算をいくつか
MM.ddYYYY
2つの数字を日付フォーマットで入力
[RS] [TIME] 4.TOOLSの[DDAYS]
例
11.252012 12.312012 DDAYS 36
2つの数字を日付フォーマットで入力
[RS] [TIME] 4.TOOLSの[DATE+]
例
11.252012 10 DATE+ 12.052012
[RS] [TIME] 4.TOOLSの[DATE]
日付に続いて時刻をHH.MMSSsで入力し[TSTR]で曜日も含めて文字列化できる。
例1
12.052012 ;日付(2012/12/5) 0.0 ;時刻(00:00) TSTR WED 12/05/12 00:00:00 ;日付文字列
例2
12.042013 ;日付(2013/12/4) 90 ;90 DATE+ ;加算 3.042014 ;計算結果 0.0 ;時刻(00:00) TSTR TUE 03/04/14 00:00:00 ;日付文字列
HP50gは数式を因数分解したり、微積分ができるらしい。自分レベルでは定積分くらいで事足りるので、その操作方法を確認。
まずEQWで対象の式を入力する。
1:'3*X^2+2'
[LS][4:CALC]で表示されるソフトメニュー[F6:INTVX]でXについての不定積分を実行する。
1:'3*(1/3*X^3)+2*X'
続けて、下限、上限の順で範囲をスタックに積む。
3:'3*(1/3*X^3)+2*X' 2:0 1:1
ここでソフトメニュー[F1:DERIV][NXT][F4:PREVA]を実行する。
1:3
先の定積分を、CEIL(X)について、0から10までやってみた。
前回と同じく、
1:'CEIL(X)'
で[INTVX]すると、出てきた不定積分結果が前回と違う表示になった。
1:'INT(CEIL(Xt),Xt,X)'
これに、0 10をスタックに積んで、[PREVA]すると、
1:'∫(0,10,CEIL(Xt),Xt)'
これを→NUMしたら、それまでほぼ瞬時に帰ってきた応答が、ぜんぜんこなくなった。
一瞬操作ミスってフリーズしたんだろうか?と心配になり、キャンセルしてみると、やりかけていたような値が返ってくる。
意を決して、ずっと放置してみると。答えが返ってきた。
所要時間約20分10秒!!
しかも、55ではなく、54.9999302884と丸めれば55にはなるが少し小さい値だった。
不定積分の結果出た関数に代入して差をとることが出来ないケースでは、小刻みに計算を繰り返す感じで、階段状に立ち上がるところで幅分三角形の部分が出来てショートしているんだろうと思った。
Wolfram|Alphaでは、階段状のグラフまで描かせようとすると標準計算時間では無理のようだが、答えは瞬時に帰ってくる。
ためしに、0から10ではなく、INTVXの結果をDUPして0から5と5から10の2回に分けて、結果を求める方法にしたら、ボタン操作にほぼ追従して55.という答えを得ることができた。
時間がかかるときは、区間を分割してやるのも有効そうだ。
今まではスタックや変数に保存した値を計算するプログラムしかしていなかったが、ポケコンBASICでよくやるINPUT文のように値の入力を促すプロンプトを表示して値入力を待つようなことはできないのか調べてみた。
まずはINPUT
スタックに以下の2つを積んで
2:入力プロンプト 1:コマンドライン(タグなどを入力)
[INPUT]を実行
すると入力待ちの状態になる。(キャプチャー出来ていないが左下に←のようなカーソルが出る。)
値を入力して[ENTER]するとスタックに文字列の状態で入力した物が保存されるので、[OBJ→]して数値化する。
もう少し高度なことが出来るのがこのINFORM
画面全体を切り替えて、ダイアログのようなものが作れるらしい。
実行前に次の5項目をスタックに積む必要がある
5:タイトル 4:入力項目のリスト、それぞれ項目名、最下行への入力ガイド、型(省略可)の 3項目のリストで構成される 3:フォーマット(横方向の分割数) 2:リセットした場合の設定値 1:ダイアログ表示時点の初期値
advanced user's reference manualの例題どおりにスタックを積んだところが以下の図
これの状態でINFORMを実行すると、
このマニュアルのサンプルでは、2列で表示するようになっているが、レベル4の項目リストで2番目が中身無しの{}になっているため、1項目目の入力欄が、2番目の場所も使用している。
これに値を入力したのが
で、[OK]すると、
のようになる。
スタックは
2:入力値を並べたリスト 1:実行結果(OK)=1
になる。
[CANCL]の場合はレベル1に0のみセットされる。
リセット操作は、ダイアログ表示中に[NXT]をするとソフトキー左端に[RESET]が表示されるので、
カーソルでReset allをしてやるとレベル2設定の値に初期化される。
一連の値をプログラム中で使うためには、リストを[LIST→]又は[OBJ→]でバラバラにした上で、ローカル変数に代入して使う感じかな。
スマホではエミュレータのDroid48を使っている。
仕事の単位に馬力(PS)が入っていない(hpとWのみ)ので、ユーザー定義単位'PS'を作ってみたが、Inconsistent Unitとエラーになって変換がうまく行かない。
試しに'PSPS'とか違う名前で登録してみたら、こっちはうまく行った。
特に予約済みの名前にはないようだけど、試しに1_PSを[UBASE]してみたら、1.E15_A^2*s^3/(kg*m^2)に変換された。「PS」では予約されていないが、ペタ・ジーメンスのようだ。これならエラーが出てもしかたない。
大文字/小文字を識別するか念のため'ps'で試してみたら、今度はピコ・セコンドになった。orz
やっぱり、違う文字列で代替するしかない。
それにしても、ユーザー定義単位を初めて使ったのがこれだから、操作そのものを誤っているのかなどいろいろ悩んでしまった。
Wolfram|Alphaでした単位換算をHP電卓でやってみる。
まず、変換したい値を単位付きで入力し、変換先の単位付き数字をスタックに積む。
次に、[LS][6:UNITS]で画面に出るソフトキーの[CONV]を押すと、
のように変換完了
Droid48(HP48GX)のSOLVEでは、金銭の時間的価値(time value of money)の計算もできるようになっている。
[RS]→[7](SOLVE)でSOLVERの一覧が表示され、5番目のSolve finance...を選択すると、TIME VALUE OF MONEY画面が表示される。(画面はPC用のEmu48の画面)
この画面のパラメータの意味は次のとおり。
住宅ローンのケースだと、現在価値は借入額、将来価値は0(完済することが目標なので)になる。
カーソルを移動させて既知の値(条件)を入力し、求めたい欄で[SOLVE]を押すと、その欄に答が代入される。(支払いタイプは期末(End)でいいようだ。)
画面の例では、1千万円を年3パーセントで35年払いの1年あたりの支払額を求めたところ。年間465,393円(切り上げ)支払うと言うことになる。
PMTにカーソルがある状態で、[ENTER]を押すと、この値がスタックに保存されるので、これに対して支払い回数をかけてやれば、支払総額が求められる。
35 *
630万円近く利息を払うことになるのかぁ
前回は通常画面に戻ってから支払い回数を掛けて総支払額を求めたが、もうひとつ別の方法がある。
[SOLVE]ソフトメニューの左側にある[AMOR]ソフトメニューがそれだ。
支払額を求めた状態で、[AMOR]を選択すると、AMORTIZEという画面に変化する。
Paymentsに最後の支払い(35)を入力して、再度[AMOR]を押すと、
Principal:(元本分)
Interest:(利息分)
Balance:(支払い残)
の3項目に値が入る。
完済回なので元本分は借入額と同じ額になっており、利息分欄に支払った利息額が、支払い残は借入額との差し引きになっている。ここは0が理想だろうけど、一定の条件を満たそうと思うとこれくらいの誤差は出ちゃうんだろうな(実際のお金は小数点以下は丸められるし)。
符号については、借り入れ側から見たお金の動きと見れば、借入額が正の値、支払った額が負の値ということで理解できるかな。
これを使うと、ローン条件が変わった場合の再計算や当初10年低くしていた金利が、その後高く変わるような支払い方式の計算をすることができる。
11年め以降の金利が5パーセントに上がると仮定して計算してみる。
まずは、10年目の残額を求める必要がある。
AMORTIZE画面で支払期に10を入力して、[AMOR]を押すと、10年目支払い時点での元本残高(810万4千円程)がBALANCEに表示される。ここで[B→PV]ソフトメニューを押すと、この残額がTVMソルバーの借入額(PV)に設定されるので、この画面から[CANCEL]で戻る。
↓
この状態で、残りの支払い回数と新しい利率を設定してPMTにカーソルを置いて[SOLVE]を押すと、新しい年間支払額が表示される。
~~~~~
実際の住宅ローンでは、ボーナス支払い分などを個別に計算し、それぞれ12や2で割った額を各月別に合計したものが月々の支払額になるようだ(年間12回支払いで支払い回数が年×12でするより利息が1年分つくから支払額は高くなる。)。
こういう細かいところはもう電卓ではなくスプレッドシートの出番かな。
2023/01/08
Primeの幾何アプリは作図条件(作図コマンドに与える座標)にユーザー変数を指定でき、この値を変更してから再描画することで都度異なる条件での作図が可能で、その結果の距離や角度を得ることができることがわかった。そこで、この機能を使って風向風速計算尺による計算を再現してみた。
Dw: 相対風向(右が正) Vw: 相対風速(ノット) Ds: 針路 Vs: 船速(ノット)
方位が0~360の範囲になるように調整する処理をユーザー関数として用意。
EXPORT Compass(D) BEGIN IF D<0 THEN RETURN D+360; ELSE IF D>360 THEN RETURN D-360; ELSE RETURN D; END; END; END;
幾何アプリに以下のように入力
☑GA point(0,0) □GB point(0,Vw) □GC half_line(GA,GB) ☑GD rotation(GA,-Dw,GC) □GE circle(GA,GB-GA) ☑GG inter(GD,GE) ☑GH point(abscissa(GG),ordinate(GG)-Vs) ☑GI segment(GG,GH) ☑GJ segment(GA,GH) ☑GK polygon(point(0,3),point(1,2),point(1,-2),point(-1,-2),point(-1,2)) //船の形、ラベル非表示
☑Dw Dw ☑Vw Vw ☑Ds Ds ☑Vs Vs ☑Dwt Compass(Ds+angle(GA,GH,GB)) ☑Vwt distance(GH,GA)
事前にユーザー変数にDw=-20、Vw=20、Ds=10、Vs=13を設定した後Plotを実行。
この計算を50gでする場合は、以下のようなベクトル計算でも求めることができる。
設定:
角度は度(DEG): (MODE→Angle Measure~~Degreesだと「DEG」、Radiansだと「RAD」、Gradsだと「GRD」)
座標は円筒座標(CYLI): (MTH→VECTR→CYLI(ディスプレイ最上部の表示が「R∠Z」になる~~RECTだと「XYZ」、SPHEだと「R∠∠」になる)
20 //相対風速: Vw(ノット) -20 //相対風向: Dw(右舷側正) →V2 [20.∠-20.] //相対風向風速のベクトル 13 //船速: Vs(ノット) 0 //ここは固定値 →V2 [13.∠0.] //船の進行ベクトル - [8.96436485151∠-49.7352486224] //真風向風速のベクトル V→ 8.96436485151 //真の風速 -49.7352486224 //ベクトルをスタック2段に分解 10 //船の針路: Ds + -39.7352486224 //船の針路を加減~真の風向 360 //風向が負の場合の処理 + 320.264751378 //真の風向
計算自体は三角関数で出来るのではあるが、ベクトルや幾何を使うと、値を入力するだけでほぼ結果が得られるというのが凄い。
HP50gでプログラムを書こうとしてあれこれマニュアルを読んでいたら、リストのない(CD-ROMにあるから見ろと書いてある)ものがあった。
内容的に見てみたいものだったので、CDを掘り出してみたが見当たらない。
検索してみたら同じ質問がフォーラムにあった。
なんでCD-ROMにないのかは分からないが、フォーラム内で紹介されているリンク先からダウンロードできた。
HP50g
いつだったか切り替えたまま使っていて、どうやって切り替えたのか判らなくなってしまっていたので、メモ
スタックに数式を置いた場合に、マニュアルにあるような教科書的な表示をさせる場合は、
DISP MODESのStack:Textbookにチェックを入れると同時に、
システムフラグ52をShow many linesにセットするする必要がある。
関連してシステムフラグ65により、レベル1のみか全スタックマルチラインにするかが切り替えられる。
RPNが結構気に入ったので、Amazonでポチった。
RPNに頭を切り替えるため、職場などで傍らにあったCASIO、SHARPの関数電卓、プログラミング電卓を封印し、PCもEmu48をインストール。どこででもRPNが使えるようにした。
職場に置いておける気軽なものが欲しくなり、ついついポチってしまった。
スタックの数や動きが50gとは違うが、軽くて使いやすい。
今年3台目のHP電卓
15c LEが配達された。
代理店のジュライが頑張ってくれて、日本語ユーザーズガイドもついていた。
[f]、[g]のグラグラ問題など色々あるが、やっぱり15cいいなぁ。