質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.49%

  • COBOL

    21questions

    COBOL(COmmon Business Oriented Langage)は、実務処理用に開発されたプログラミング言語です。

COBOL言語を用いた逆ポーランド記法での電卓作成について

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 886

dsk_27sim

score 2

初めてこういった質問サイトに投稿しますため、読みづらい文章ではあると思いますが、ご容赦ください。

前提・実現したいこと

現在、OpenCOBOLを使ってCOBOLの学習を進めています。
学習の一環として、以前学校で習ったC言語で逆ポーランド記法を用いて、電卓を作成した経験から、
COBOLでも同じことをしてみようと思いGoogleで検索したところ、
先駆者様が既にネットワーク上に、COBOLで実装したコードをアップロードしていらっしゃったので、
それをサンプルコードとして、読み進めながら自分でもCOBOLで実装を試みました。

エラーメッセージも出ずにすんなりとコンパイルが通り、
3 4 + と入力してみたところ、
予想される結果は”7”のはずなのですが、
私の作成したプログラムでは”8”が出力されてしまいました。

先駆者様のプログラムも同じPC上で実行し、同じ値を入力してみたところ、
しっかりと7が出力されていました。

その後、サンプルコードと自分の書いたコードを見比べて確認してみても、
自分の目にはおかしいなと思うところが見当たらず、煮詰まっています。

期待される動作とは矛盾しているコードがあるのはわかりきっているのですが、
私には見つけることが困難なため、お力添えをいただければと思います。

 先駆者様のソースコード

お手数をお掛けしますが、直に他人のソースコードを貼るのはどうかと思い、リンクを貼らさせて頂きました。

先駆者様のソースコードです

私のソースコード

DENTIFICATION DIVISION.
  PROGRAM-ID. rpncalc. *>逆ポーランド記法を用いた計算機のプログラム

DATA DIVISION.
  WORKING-STORAGE SECTION.
    01 fomula      PIC X(20).          *> 計算式を格納する変数(100はとりすぎ)
    01 fomula_pos  PIC 99.            *> 格納した計算式を解析するための字数カウント(position)-
                                       *> -厳密には FUNCTION LENGTH(fomula)と組み合わせて使う
    01 token       PIC X.              *> 文字や数字を汲み取るための変数

    01 temp        PIC 9(4).           *> 保持用変数

    01 first_term  PIC 9(4).           *> 初項
    01 second_term PIC 9(4).           *> 次項

    01 stack_pos PIC 9(2) VALUE 1.       *> スタック位置を見る変数

    01 stack
      03 stack_data PIC 9999 OCCURS 10 VALUE 0.
                                       *> 実際のスタック領域 長さは10
    01 result PIC Z(4).                *> 最終的に表示される結果


PROCEDURE DIVISION.


    Main SECTION.

    DISPLAY "enter the fomula > " WITH NO ADVANCING.
      *> 計算式を入力
    ACCEPT fomula.
    MOVE 1 TO fomula_pos.

    PERFORM UNTIL fomula_pos > FUNCTION LENGTH(fomula)
      *> fomulaの字数分をwhileする

      MOVE fomula(fomula_pos:fomula_pos) TO token
      *> MOVEの部分参照を利用して、posの"今いる"部分を参照し、TOKENにより判定

      IF token NOT = " " THEN
        PERFORM Evaluate_Token
      END-IF

      *> もし現在位置が空白じゃなかったらEvaluate_Token節に飛ぶ(外PERFORM文)
      *> 現在位置が空白であればそのままpos++でスルー

        ADD 1 TO fomula_pos

    END-PERFORM.

    PERFORM Result_Display.

    STOP RUN.

  Evaluate_Token SECTION.

    IF token IS NUMERIC THEN
      *> もしtokenに数字が格納されていたら

      MOVE token TO temp
      *> tempにtokenを格納し、その値をスタック

    ELSE
      *> もし演算子がfomula_posに観測されたら、

      PERFORM Pop
        MOVE temp TO first_term
      *> 先頭の数値を初項に移す
      PERFORM Pop
        MOVE temp TO second_term
      *> 2つ目の数値(と考えられるもの)を2項目に移す

      EVALUATE token
        WHEN "+"
          COMPUTE temp = first_term + second_term ;
        WHEN "-"
          COMPUTE temp = first_term - second_term ;
        WHEN "*"
          COMPUTE temp = first_term * second_term ;
        WHEN "/"
          COMPUTE temp = first_term / second_term ;

      END-EVALUATE

      PERFORM Push
      *> もし数字であればtempはそのままpushされることになる (remind: )

    END-IF.


  Push SECTION.
      *> tempに保持されている値をスタック領域にpush(保存・投げ込む)

    IF stack_pos <= 10 THEN
      MOVE temp TO stack_data(stack_pos)
      ADD 1 TO stack_pos
    END-IF.

  Pop SECTION.
      *> tempに、スタックに保存されている値をpopして格納(取り出す)

      IF stack_pos > 1 THEN
        SUBTRACT 1 FROM stack_pos
        MOVE stack_data(stack_pos) TO temp

      END-IF.

  Result_Display SECTION.

    PERFORM Pop.
      MOVE temp TO result.
      DISPLAY "Result : " result.

試したこと

・ > 4 3 + で7が出るところに8が出力されてしまいます。
・ > 4 4 + では8が出力されます。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+2

数値を push する位置がおかしくないですか?

else ブロックではなく、then ブロックじゃないかな?

then ブロックでスタックすると書いてあるけど、してないように見えますけど

then ブロックは入力値が数値の時で、else は演算子の時ですよね?

だとすると else ブロックに push があっても意味がないですよね?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/18 17:02

    PERFORM Push
    *> もし数字であればtempはそのままpushされることになる (remind: )
    END-IF.

    の箇所を、
    END-IF.
    PERFORM Push
    *> もし数字であればtempはそのままpushされることになる (remind: )

    に修正したところ 4 3 +で7が出力されました!
    助かりました。ありがとうございました。

    キャンセル

関連した質問

同じタグがついた質問を見る

  • COBOL

    21questions

    COBOL(COmmon Business Oriented Langage)は、実務処理用に開発されたプログラミング言語です。