逆ポーランド電卓 by Odakaz

再生

 逆ポーランド記法を使った電卓プログラムだ。
 操作はキーボードから。数字や演算子を打ち込んで、スペースキーでスタックにプッシュする(積む)ことになる。
 入力中の値のクリアは「C」、スタックも含めた全クリアは「A」。「Q」でプログラムの終了になる。
 入力できる値の範囲は-99999~99999。扱える値は-524287.999~524287.999となっている。

作ったのはこの人

Odakaz

ライフゲームに続いて、再びコンピューターのイロハにかかわるプログラムを投稿してくれたOdakaz君の本職はプログラマー。仕事柄か、今回も「おそらく必要ないだろうなと思いつつ、サブルーチンが防御的なコードになっていたり」とのこと。さすがだね。


 CHECK POiNT 

ワンパク
ギャク……ポーランド……?

インテリ
ちょっと説明が必要かな。僕らが普通に使う「1+1=2」という計算式(中置記法)は、あまりコンピューターの考え方には合ってないんだ。逆にプログラム的に正しいのが「1,1,+」という「逆ポーランド記法」だね。

博士
計算に必要な数字をそれぞれ「スタック」に積んで、+-*/の演算子が来たらスタックを処理する、ということじゃな。……わかりづらかったかの?

ワンパク
スタ……?

神崎
え、えーと、「逆ポーランド記法」で検索すると分かりやすい説明がいろいろ出てくるよ。

博士
ウム。プログラム……というより、コンピューターによる計算の概念を理解するのにうってつけの考え方なのじゃ。今スグに役立つとは限らんが、教養として知っておくのも悪くないぞい。

プログラムリスト

  1. ’┌──────────────────────────┐
  2. ’│RPNテ゛ンタク 2011/03/29 ODAKAz│
  3. ’└──────────────────────────┘
  4. ’┌────┐
  5. ’│ショキカ│
  6. ’└────┘
  7. VISIBLE 1,1,1,1,1,1
  8. CLEAR
  9. ’ бアツカエル アタイノ サイタ゛イチ
  10. MAX_NUM=524287.999
  11. ’ бスタック
  12. S=100:T=0:DIM ST(S)
  13. ’ бニュウリョク
  14. B$=””
  15. ’ бモート゛
  16. M_WAIT  =0 ’ニュウリョクマチ
  17. M_NUMBER=1 ’スウシ゛ヲ イレテイル
  18. M_CAN_OP=2 ’エンサ゛ンシヲ イレテモ イイ
  19. M_OPONLY=3 ’エンサ゛ンシタ゛ケ イレテイイ
  20. M_OP    =4 ’エンサ゛ンシヲ イレタ
  21. M=M_WAIT
  22. ’ бモート゛コ゛トノ ニュウリョク カノウ モシ゛
  23. DIM A_KEY$(5)
  24. A_KEY$(M_WAIT)  =”0123456789-”
  25. A_KEY$(M_NUMBER)=”0123456789 ”
  26. A_KEY$(M_CAN_OP)=”0123456789+-*/”
  27. A_KEY$(M_OPONLY)=”+-*/”
  28. A_KEY$(M_OP)    =”0123456789- ”
  29. ’┌────────┐
  30. ’│カ゛メンショキカ│
  31. ’└────────┘
  32. CLS
  33. LOCATE 0,0:PRINT ”┌RPN CALC──────┐”
  34. LOCATE 0,1:PRINT ”│>>            │”
  35. LOCATE 0,2:PRINT ”└──────────────┘
  36. LOCATE 1,3:PRINT ”┌─────┐”
  37. LOCATE 1,4:PRINT ”│Stack│”
  38. LOCATE 1,5:PRINT ”└┬────┴─────┐”
  39. LOCATE 0,6
  40. FOR I=1 TO 16
  41.  PRINT ”  │          │”
  42. NEXT
  43. PRINT  ”  └──────────┘”
  44. LOCATE 16,0:PRINT ”┌KEY───────────┐”
  45. LOCATE 16,1:PRINT ”│C:ニュウリョク クリア  │”
  46. LOCATE 16,2:PRINT ”│A:オール クリア     │”
  47. LOCATE 16,3:PRINT ”│SPACE:スタックヘ   │”
  48. LOCATE 16,4:PRINT ”│Q:シュウリョウ      │”
  49. LOCATE 16,5:PRINT ”└──────────────┘”
  50. LOCATE 16,7:PRINT ”┌MESSAGE───────┐”
  51. LOCATE 16,8:PRINT ”│              │”
  52. LOCATE 16,9:PRINT ”└──────────────┘”
  53. ’┌───┐
  54. ’│メイン│
  55. ’└───┘
  56. @MAIN
  57. GOSUB @DISPLAY
  58. GOSUB @IN
  59. MSG$=””
  60. ON M GOSUB @WAIT,@NUMBER,@CAN_OP,@OPONLY,@OP
  61. GOTO @MAIN
  62. ’┌─────────┐
  63. ’│カ゛メンヒョウシ゛│
  64. ’└─────────┘
  65. @DISPLAY
  66.  LOCATE 3,1:PRINT B$;”      ”
  67.  FOR Y=6 TO 21
  68.   LOCATE 3,Y:PRINT ”          ”
  69.  NEXT
  70.  IF T==0 THEN RETURN
  71.  DY=T
  72.  IF DY>16 THEN DY=16
  73.  FOR I=1 TO DY
  74.   LOCATE 3,21-DY+I
  75.   D$=”          ”+STR$(ST(T-I))
  76.   PRINT MID$(D$,LEN(D$)-10,10)
  77.  NEXT
  78.  LOCATE 17,8:PRINT MID$(MSG$+”              ”,0,14)
  79. RETURN
  80. ’┌────────┐
  81. ’│キーニュウリョク│
  82. ’└────────┘
  83. @IN
  84.  ’бニュウリョクモシ゛ノ シュルイ
  85.  IS_OP=FALSE:IS_MINUS=FALSE:IS_NUM=FALSE:IS_SP=FALSE
  86.  K$=INKEY$()
  87.  ’スヘ゛テノ モート゛テ゛ キョウツウ
  88.  IF K$==”C” THEN GOSUB @COM_C:RETURN
  89.  IF K$==”A” THEN GOSUB @COM_A:RETURN
  90.  IF K$==”Q” THEN @PRGEND
  91.  ’ルーフ゜ナイテ゛RETURNスルト オカシクナルノテ゛ ルーフ゜カ゛ オワッテカラ ハンテイ
  92.  E=FALSE
  93.  FOR I=0 TO LEN(A_KEY$(M))-1
  94.   IF K$==MID$(A_KEY$(M),I,1) THEN E=TRUE
  95.  NEXT
  96.  IF E THEN GOSUB @IN_TYPE:RETURN
  97.  GOTO @IN
  98. RETURN
  99. ’ニュウリョク クリア
  100. @COM_C
  101.  K$=””
  102.  GOSUB @CLR_BUFF
  103.  GOSUB @NEXTBYST
  104. RETURN
  105. ’オールクリア
  106. @COM_A
  107.  T=0
  108.  GOSUB @COM_C
  109. RETURN
  110. ’┌─────────────────────────┐
  111. ’│ニュウリョクサレタ モシ゛ノ シュルイヲ ハンテイ│
  112. ’└─────────────────────────┘
  113. @IN_TYPE
  114.  IF K$==”” THEN RETURN
  115.  ’エンサ゛ンシ?
  116.  IS_OP=K$==”+” OR K$==”-” OR K$==”*” OR K$==”/”
  117.  IF IS_OP THEN O$=K$
  118.  ’マイナス?
  119.  IS_MINUS=K$==”-”
  120.  ’スウシ゛?
  121.  KASC=ASC(K$)
  122.  IS_NUM=KASC>=ASC(”0”) AND KASC<=ASC(”9”)
  123.  ’スヘ゜ース?
  124.  IS_SP=K$==” ”
  125. RETURN
  126. ’┌─────────────┐
  127. ’│ニュウリョクマチ モート゛│
  128. ’└─────────────┘
  129. @WAIT
  130.  GOSUB @ADD_BUFF
  131.  IF IS_MINUS THEN M=M_OP:RETURN
  132.  IF IS_NUM THEN M=M_NUMBER
  133. RETURN
  134. ’┌────────────────┐
  135. ’│スウシ゛ ニュウリョク モート゛│
  136. ’└────────────────┘
  137. @NUMBER
  138.  ’スウシ゛
  139.  IF IS_NUM THEN GOSUB @ADD_NUM:RETURN
  140.  ’スヘ゜ース
  141.  IF IS_SP THEN GOSUB @PUSH_NUM
  142. RETURN
  143. ’5ケタ マテ゛ナラ ニュウリョク カノウ
  144. @ADD_NUM
  145.  L=LEN(B$)
  146.  IF MID$(B$,0,1)==”-” THEN L=L-1
  147.  IF L<5 THEN GOSUB @ADD_BUFF
  148. RETURN
  149. ’スウチヲ スタックニ PUSH
  150. @PUSH_NUM
  151.  V=VAL(B$)
  152.  GOSUB @PUSH
  153.  GOSUB @CLR_BUFF
  154.  GOSUB @NEXTBYST
  155. RETURN
  156. ’┌──────────────┐
  157. ’│エンサ゛ン カノウ モート゛│
  158. ’└──────────────┘
  159. @CAN_OP
  160.  GOSUB @ADD_BUFF
  161.  IF IS_NUM THEN M=M_NUMBER:RETURN
  162.  IF IS_OP THEN M=M_OP
  163. RETURN
  164. ’┌─────────────┐
  165. ’│エンサ゛ン ノミ モート゛│
  166. ’└─────────────┘
  167. @OPONLY
  168.  IF IS_OP THEN GOSUB @ADD_BUFF:M=M_OP
  169. RETURN
  170. ’┌───────────┐
  171. ’│エンサ゛ンシ モート゛│
  172. ’└───────────┘
  173. @OP
  174.  IF IS_SP AND T>=2 THEN GOSUB @CALC:RETURN
  175.  IF IS_NUM AND O$==”-” AND T<S THEN GOSUB @OPTONUM
  176. RETURN
  177. ’ケイサン
  178. @CALC
  179.  GOSUB @CLR_BUFF
  180.  ’0シ゛ョサン タイサク
  181.  IF O$==”/” AND ST(T-1)==0 THEN GOSUB @ZERO_DIV:RETURN
  182.  ’オーハ゛ーフロー スルナラ ケイサンヲ チュウタ゛ン
  183.  GOSUB @CHKOVER
  184.  IF IS_OVER THEN GOSUB @R_OVER:RETURN
  185.  GOSUB @POP
  186.  IF O$==”+” THEN V=L_VAL+R_VAL
  187.  IF O$==”-” THEN V=L_VAL-R_VAL
  188.  IF O$==”*” THEN V=L_VAL*R_VAL
  189.  IF O$==”/” THEN V=L_VAL/R_VAL
  190.  GOSUB @PUSH
  191.  GOSUB @NEXTBYST
  192. RETURN
  193. ’オーハ゛ーフロー チェック
  194. @CHKOVER
  195.  IS_OVER=FALSE
  196.  R_TMP=ST(T-1):L_TMP=ST(T-2)
  197.  IF O$==”+” AND SGN(L_TMP)==SGN(R_TMP) THEN @CHK1
  198.  IF O$==”-” AND SGN(L_TMP)!=SGN(R_TMP) THEN @CHK1
  199.  IF O$==”*” AND R_TMP!=0 THEN @CHK2
  200.  RETURN
  201.  ’タシサ゛ン or ヒキサ゛ン
  202.  @CHK1
  203.  IS_OVER=MAX_NUM-ABS(R_TMP)<ABS(L_TMP)
  204.  RETURN
  205.  ’カケサ゛ン
  206.  @CHK2
  207.  IS_OVER=MAX_NUM/ABS(R_TMP)<ABS(L_TMP)
  208. RETURN
  209. ’オーハ゛ーフローヲ ツウチ
  210. @R_OVER
  211.  MSG$=”OVERFLOW!!”
  212.  O$=””
  213.  GOSUB @NEXTBYST
  214. RETURN
  215. ’スウシ゛ ニュウリョク モート゛ヘ
  216. @OPTONUM
  217.  GOSUB @ADD_BUFF
  218.  M=M_NUMBER
  219. RETURN
  220. ’0シ゛ョサンハ ムシスル
  221. @ZERO_DIV
  222.  O$=””
  223.  GOSUB @NEXTBYST
  224. RETURN
  225. ’スタックノ シ゛ョウタイニヨッテ ツキ゛ノ モート゛ヲ キメル
  226. @NEXTBYST
  227.  IF T>=S THEN M=M_OPONLY:RETURN
  228.  IF T>=2 THEN M=M_CAN_OP:RETURN
  229.  M=M_WAIT
  230. RETURN
  231. ’┌────────────────┐
  232. ’│ニュウリョク ハ゛ッファ ソウサ│
  233. ’└────────────────┘
  234. @ADD_BUFF
  235.  B$=B$+K$
  236. RETURN
  237. @CLR_BUFF
  238.  B$=””
  239. RETURN
  240. ’┌────────┐
  241. ’│スタック ソウサ│
  242. ’└────────┘
  243. @PUSH
  244.  IF T>=S THEN RETURN
  245.  ST(T)=V:T=T+1
  246. RETURN
  247. @POP
  248.  IF T<2 THEN RETURN
  249.  R_VAL=ST(T-1)
  250.  L_VAL=ST(T-2)
  251.  T=T-2
  252. RETURN
  253. ’┌──────────────┐
  254. ’│フ゜ロク゛ラム シュウリョウ│
  255. ’└──────────────┘
  256. @PRGEND
  257. CLS:CLEAR
  258. END