新しいコンパイラーは、3.1415926E0 や 1E-02 などの FLOAT DECIMAL リテラルを、この リテラルが使用されているコンテキストは調べずに、この リテラルの属性のみを調べて、内部浮動小数点表記に変換します。
例えば、3.1415296E0 の属性は FLOAT DEC(8) であるため、新しいコン パイラーは、この値を長精度浮動小数点に変換します。 しかし、1E-02 の属性は FLOAT DEC(1) であるため、新しいコンパイラー は、この値を短精度浮動小数点に変換します。
リテラルが代入または INITIAL 文節で使用されている場合、コンパイラー は、必要に応じて、このリテラルの浮動小数点値を代入先または初期化対象の属 性に変換します。
ただし従来のコンパイラーは、このようなリテラルが使用されているコンテキ ストを調べて、リテラルを直接その対象の属性に変換します。 従来のコンパイラーの動作は、PL/I 式評価に関する規則に厳密に従っていない ため、新しいコンパイラーの場合とは異なる結果が生成されることがありま す。 次のコード・フラグメントを見てください。
dcl z float dec(06) init(0); dcl s float dec(06); dcl q float dec(17); s = 1e-2; q = s; put skip data( q ); q = 1e-2; put skip data( q ); q = 1e-2 + z; put skip data( q );
上記の q. への 3 つの代入のすべてにおいて、代入元の属性は短 精度浮動小数点数の属性であり、代入元の値は同じになるはずです。 しかし従来のコンパイラーでは、3 つの PUT ステートメントの結 果は次のようになります。
Q= 9.999997913837432861E-03; Q= 9.999999999999999999E-03; Q= 9.999999999999999999E-03;
新しいコンパイラーでは、3 つの PUT ステートメントの結果は 次のようになります。
Q= 9.999997913837432860E-03; Q= 9.999997913837432860E-03; Q= 9.999997913837432860E-03;
このような相違は、正確に表現できない float 型リテラルについてのみ発 生します (同値の 2 進小数がない 1E-2 のような小数など)。
上記のような状態をアラートするために、 コンパイラーは、正確に表現できない短精度浮動小数点リテラルを検出すると、 メッセージ IBM1065I を出します。
従来のコンパイラーを使用した場合と同じ結果を得るには、次のいずれかの 方法でソースを変更する必要があります。
例えば、1E-2 を長精度浮動小数点値にするには、FLOAT(.01,7) として指定し、拡張浮動小数点値にするには、FLOAT(.01,17) として指定 します。
例えば、1E-2 を長精度浮動小数点値にするには、1.000000E-2 として指定し、拡張浮動小数点値にするには、1.0000000000000000E-2 として指定します。
例えば、1E-2 を長精度浮動小数点値にするには、1D-2 として指 定し、拡張浮動小数点値にするには、1Q-2 として指定しま す。
上記の 1 つ目と 2 つ目の変更は新旧のコンパイラーで許容されますが (どち らのコンパイラーでも同じ結果が生成されます)、3 つ目の変更は、新しいコンパ イラーでのみ有効なので注意してください。