■元の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;