コードの一部をコンパイルしているときに、次のようなメッセージが表示され ることがあります。
IBM1099I W FIXED DEC(7,2) operand will be converted to FIXED
BIN(25,7). Significant digits may be lost.
メッセージ内の属性は異なる場合がありますが、これと同じメッセージを 生成するコードの一部の例を次に示します。
DCL
1 REC_OUT,
03 AVAIL FIXED BIN(31),
03 TOTAL_SPARE FIXED DECIMAL(7,2),
03 WORK_TOTAL FIXED DECIMAL(7,2);
AVAIL = 17;
WORK_TOTAL = 12.2;
TOTAL_SPARE = AVAIL + WORK_TOTAL;
新旧のコンパイラーは最後の代入をまったく同じ方法で実行し、どちら も、TOTAL_SPARE に 29.19 という値を代入します (予測される 29.20 という値ではなく)。 ただし、新しいコンパイラーのみが、このステートメントをさらに詳しく調べ ることを促すメッセージを発行します。
このメッセージの意味、および一見間違いに思える上記のス テートメントの結果が正しい理由を理解するには、指数演算以外の算術演算に 適用される次の PL/I 規則をもう一度確認する必要があります。
したがって、FIXED BIN(31,0) 変数 AVAIL を FIXED DEC(7,2) 変数 WORK_TOTAL に加算した場合は、上記の規則に従って、 DEC(7,2) オペランドが強制的に BIN(25,7) に変換されます。
しかし 12.20 は、BIN(25,7) として正確に表せないため、実際には次の式 により変換されます。
( bin(12.20,31,0) * 2**7 ) / 10**2
この結果、約 12.195 という値が得られます。
この値に 17 を加算して変換し戻すと 29.19 という値が得られます。
上記のコンパイラーの動作はすべて正しいですが、おそらくユーザーの希 望に沿うものではないでしょう。その場合は、DECIMAL 組み込み関数を BINARY オペランドに適用するか、または新しいコンパイラー・オプション RULES(ANS) を指定することにより、 この演算を強制的に DECIMAL で実行することができます。
RULES(ANS) を使用した場合、スケールされた FIXED BIN は使用できず 、変換規則は、次のように経験の少ないユーザーが予想するものに近くなりま す。
if both operands are FIXED, then
if either has a non-zero scale, any BIN becomes DEC
したがって、BIN(31,0) を DEC(7,2) に加算した 場合、BIN(31,0) は DEC(10,0) に変換され、どの値も失われることはありません。
上記と同じ考慮事項が、次の顧客コード・フラグメントにも適用されます。
dcl a dec fixed(15,3) init(2500000);
dcl zero bin fixed(31) init(0);
if (a ¬= zero) then
put skip edit('dec fixed ¬= Zero')(a);
else
put skip edit('dec fixed = Zero')(a);
DEC(15,3) オペランドは BIN(31,10) に変換されます。
しかし BIN(31,10) に保持できる最大値は、2**21 すなわち 2_097_152 です。
したがって、この変換は正常に実行することができず、SIZE 条件が有効に なっている場合は、SIZE 条件が発生します。 SIZE 条件が有効になっていない場合は、このコードは間違っており、変換を 実行するために生成された CVB 命令によって、ZERODIVIDE 条件が発生します。
この場合も、新しいコンパイラーは該当する次のメッセージを発行します。
IBM1099I W FIXED DEC(15,3) operand will be converted
to FIXED BIN(31,10). Significant digits may be lost.
最後に、この場合も、RULES(ANS) コンパイラー・オプションを使用するか、 または DEC 組み込み関数を BINARY オペランドに適用することにより、この コードを修正することができます。