1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

4-5. 元のRPG3と生成されたコード

1
Posted at

■元のRPG3

RENRITSU.RPG
      *%METADATA          *
      * %TEXT 二次方程式  *
      *%EMETADATA         *
     FRENRITSUCF  E                    WORKSTN
     C                     DO   *HIVAL
     C*入力画面
     C                     Z-ADD*ZERO     VALA
     C                     Z-ADD*ZERO     VALB
     C                     Z-ADD*ZERO     VALC
     C                     EXFMTFMT11
     C*F3で終了
     C           *IN03     IFEQ *ON
     C                     SETON                     LR
     C                     RETRN
     C                     ENDIF
     C*入力値のチェックと計算
     C                     EXSR SR@KSN
     C*応答画面
     C                     EXFMTFMT12
     C*F3で終了
     C           *IN03     IFEQ *ON
     C                     SETON                     LR
     C                     RETRN
     C                     ENDIF
     C*
     C                     ENDDO
     C* サブルーチン
     C           SR@KSN    BEGSR
     C***** 二次方程式の解の公式( AX^2 + BX + C = 0を解く)
     C*****  ( X = -B +- SQRT(B^2 - 4AC) ) / 2A
     C* 判別式(B*B-4*A*C)を求める
     C           VALB      MULT VALB      W#T1    52
     C           4         MULT VALA      W#T2    52
     C           W#T2      MULT VALC      W#T2
     C           W#T1      SUB  W#T2      W#HANB  52
     C* 判別式が負の場合実数解はない
     C           W#HANB    IFLT 0
     C                     MOVEL*ON       *IN60
     C                     MOVEL*OFF      *IN70
     C                     ELSE
     C                     MOVEL*OFF      *IN60
     C                     MOVEL*ON       *IN70
     C* 解の計算
     C           -1        MULT VALB      W#T3    52
     C           2         MULT VALA      W#T4    52
     C                     Z-ADD0         ANS1    52
     C                     Z-ADD0         ANS2    52
     C* W#T4(2*A)=0は、分母が0なので、解の公式では計算できない
     C           W#T4      IFEQ 0
     C                     MOVEL*ON       *IN61
     C                     MOVEL*OFF      *IN70
     C                     ELSE
     C                     MOVEL*OFF      *IN61
     C                     MOVEL*ON       *IN70
     C* 判別式の解が0の場合は、-B/2Aになるので次の計算になる
     C           W#HANB    IFEQ 0
     C           W#T3      DIV  W#T4      ANS1
     C           W#T3      DIV  W#T4      ANS2
     C* 解の公式の計算(-B +- SQRT(W#HANB)) / (2 * A)
     C                     ELSE
     C                     SQRT W#HANB    W#T5    52
     C           W#T3      ADD  W#T5      W#T6    52
     C           W#T6      DIV  W#T4      ANS1
     C           W#T3      SUB  W#T5      W#T6
     C           W#T6      DIV  W#T4      ANS2
     C                     ENDIF
     C                     ENDIF
     C                     ENDIF
     C                     ENDSR

■生成されたFFRPG

FRENRITU.RPGLE
      *%METADATA          *
      * %TEXT 二次方程式  *
      *%EMETADATA         *
**FREE
// =====================================================
// FRENRITU - 二次方程式 AX^2 + BX + C = 0 の解を求める
// RENRITSU.RPG (RPG3/OPM) からの変換
// =====================================================
DCL-F RENRITSU WORKSTN;

DCL-S W#T1  PACKED(5:2);
DCL-S W#T2  PACKED(5:2);
DCL-S W#T3  PACKED(5:2);
DCL-S W#T4  PACKED(5:2);
DCL-S W#T5  PACKED(5:2);
DCL-S W#T6  PACKED(5:2);
DCL-S W#HANB PACKED(5:2);

// 主処理ループ
DOW *ON;

  // 入力画面
  VALA = 0;
  VALB = 0;
  VALC = 0;
  EXFMT FMT11;

  // F3 で終了
  IF *IN03 = *ON;
    *INLR = *ON;
    RETURN;
  ENDIF;

  // 入力値のチェックと計算
  EXSR SR@KSN;

  // 応答画面
  EXFMT FMT12;

  // F3 で終了
  IF *IN03 = *ON;
    *INLR = *ON;
    RETURN;
  ENDIF;

ENDDO;

// =====================================================
// SR@KSN - 二次方程式の解の公式
//   ( AX^2 + BX + C = 0 を解く )
//   X = ( -B +- SQRT(B^2 - 4AC) ) / 2A
// =====================================================
BEGSR SR@KSN;

  // 判別式 (B*B - 4*A*C) を求める
  W#T1   = VALB * VALB;
  W#T2   = 4 * VALA * VALC;
  W#HANB = W#T1 - W#T2;

  // 判別式が負の場合、実数解はない
  IF W#HANB < 0;
    *IN60 = *ON;
    *IN70 = *OFF;
  ELSE;
    *IN60 = *OFF;
    *IN70 = *ON;

    W#T3 = -1 * VALB;
    W#T4 = 2  * VALA;
    ANS1 = 0;
    ANS2 = 0;

    // W#T4 (2*A) = 0 は分母が 0 なので解の公式で計算できない
    IF W#T4 = 0;
      *IN61 = *ON;
      *IN70 = *OFF;
    ELSE;
      *IN61 = *OFF;
      *IN70 = *ON;

      // 判別式が 0 の場合は -B/2A
      IF W#HANB = 0;
        ANS1 = W#T3 / W#T4;
        ANS2 = W#T3 / W#T4;
      ELSE;
        // 解の公式 (-B +- SQRT(W#HANB)) / (2*A)
        W#T5 = %SQRT(W#HANB);
        W#T6 = W#T3 + W#T5;
        ANS1 = W#T6 / W#T4;
        W#T6 = W#T3 - W#T5;
        ANS2 = W#T6 / W#T4;
      ENDIF;
    ENDIF;
  ENDIF;

ENDSR;

■生成されたテストコード

TFRENITR.RPGLE
      *%METADATA              *
      * %TEXT 二次方程式テスト *
      *%EMETADATA             *
**FREE
CTL-OPT NOMAIN;

// =====================================================
// RPGUnit API (RPGUNIT/RPGUNIT1,TESTCASE)
// =====================================================
DCL-PR assert EXTPROC('assert') OPDESC;
  condition  IND          CONST;
  msgIfFalse VARCHAR(256) CONST;
END-PR;

DCL-PR iEqual EXTPROC('iEqual') OPDESC;
  expected PACKED(31:0) CONST;
  actual   PACKED(31:0) CONST;
END-PR;

DCL-PR fail EXTPROC('fail') OPDESC;
  msg VARCHAR(256) CONST;
END-PR;

// =====================================================
// CalcKsn prototype (SR@KSN equivalent)
// =====================================================
DCL-PR CalcKsn;
  PI_A    PACKED(2:0) VALUE;
  PI_B    PACKED(2:0) VALUE;
  PI_C    PACKED(2:0) VALUE;
  PO_ANS1 PACKED(5:2);
  PO_ANS2 PACKED(5:2);
  PO_IN60 IND;
  PO_IN61 IND;
  PO_IN70 IND;
END-PR;

// =====================================================
// TEST_JITSUSU2: 1X^2 - 3X + 2 = 0 => X=2, X=1
// =====================================================
DCL-PROC TEST_JITSUSU2 EXPORT;
  DCL-S ANS1 PACKED(5:2);
  DCL-S ANS2 PACKED(5:2);
  DCL-S IN60 IND;
  DCL-S IN61 IND;
  DCL-S IN70 IND;

  CalcKsn(1 : -3 : 2 : ANS1 : ANS2 : IN60 : IN61 : IN70);

  assert(IN60 = *OFF        : 'IN60 should be *OFF');
  assert(IN61 = *OFF        : 'IN61 should be *OFF');
  assert(IN70 = *ON         : 'IN70 should be *ON');
  assert(ANS1 = 2           : 'ANS1 should be 2.00');
  assert(ANS2 = 1           : 'ANS2 should be 1.00');
END-PROC;

// =====================================================
// TEST_JUUKAI: 1X^2 - 2X + 1 = 0 => X=1 (double root)
// =====================================================
DCL-PROC TEST_JUUKAI EXPORT;
  DCL-S ANS1 PACKED(5:2);
  DCL-S ANS2 PACKED(5:2);
  DCL-S IN60 IND;
  DCL-S IN61 IND;
  DCL-S IN70 IND;

  CalcKsn(1 : -2 : 1 : ANS1 : ANS2 : IN60 : IN61 : IN70);

  assert(IN60 = *OFF        : 'IN60 should be *OFF');
  assert(IN61 = *OFF        : 'IN61 should be *OFF');
  assert(IN70 = *ON         : 'IN70 should be *ON');
  assert(ANS1 = 1           : 'ANS1 should be 1.00');
  assert(ANS2 = 1           : 'ANS2 should be 1.00');
END-PROC;

// =====================================================
// TEST_MUKAI: 1X^2 + 0X + 1 = 0 => no real roots
// =====================================================
DCL-PROC TEST_MUKAI EXPORT;
  DCL-S ANS1 PACKED(5:2);
  DCL-S ANS2 PACKED(5:2);
  DCL-S IN60 IND;
  DCL-S IN61 IND;
  DCL-S IN70 IND;

  CalcKsn(1 : 0 : 1 : ANS1 : ANS2 : IN60 : IN61 : IN70);

  assert(IN60 = *ON  : 'IN60 should be *ON');
  assert(IN70 = *OFF : 'IN70 should be *OFF');
END-PROC;

// =====================================================
// TEST_HITSUJI: A=0 => not quadratic
// =====================================================
DCL-PROC TEST_HITSUJI EXPORT;
  DCL-S ANS1 PACKED(5:2);
  DCL-S ANS2 PACKED(5:2);
  DCL-S IN60 IND;
  DCL-S IN61 IND;
  DCL-S IN70 IND;

  CalcKsn(0 : 2 : 1 : ANS1 : ANS2 : IN60 : IN61 : IN70);

  assert(IN61 = *ON  : 'IN61 should be *ON');
  assert(IN70 = *OFF : 'IN70 should be *OFF');
END-PROC;

// =====================================================
// CalcKsn body (SR@KSN logic)
// =====================================================
DCL-PROC CalcKsn;
  DCL-PI *N;
    PI_A    PACKED(2:0) VALUE;
    PI_B    PACKED(2:0) VALUE;
    PI_C    PACKED(2:0) VALUE;
    PO_ANS1 PACKED(5:2);
    PO_ANS2 PACKED(5:2);
    PO_IN60 IND;
    PO_IN61 IND;
    PO_IN70 IND;
  END-PI;
  DCL-S W#T1   PACKED(5:2);
  DCL-S W#T2   PACKED(5:2);
  DCL-S W#T3   PACKED(5:2);
  DCL-S W#T4   PACKED(5:2);
  DCL-S W#T5   PACKED(5:2);
  DCL-S W#T6   PACKED(5:2);
  DCL-S W#HANB PACKED(5:2);

  W#T1   = PI_B * PI_B;
  W#T2   = 4 * PI_A * PI_C;
  W#HANB = W#T1 - W#T2;

  IF W#HANB < 0;
    PO_IN60 = *ON;
    PO_IN70 = *OFF;
  ELSE;
    PO_IN60 = *OFF;
    PO_IN70 = *ON;
    W#T3    = -1 * PI_B;
    W#T4    = 2  * PI_A;
    PO_ANS1 = 0;
    PO_ANS2 = 0;

    IF W#T4 = 0;
      PO_IN61 = *ON;
      PO_IN70 = *OFF;
    ELSE;
      PO_IN61 = *OFF;
      PO_IN70 = *ON;

      IF W#HANB = 0;
        PO_ANS1 = W#T3 / W#T4;
        PO_ANS2 = W#T3 / W#T4;
      ELSE;
        W#T5    = %SQRT(W#HANB);
        W#T6    = W#T3 + W#T5;
        PO_ANS1 = W#T6 / W#T4;
        W#T6    = W#T3 - W#T5;
        PO_ANS2 = W#T6 / W#T4;
      ENDIF;
    ENDIF;
  ENDIF;
END-PROC;

目次へ

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?