Rational Developer for System z
Enterprise PL/I for z/OS, Version 3.8, コンパイラーおよびランタイム 移行ガイド

スケール付き FIXED BINARY からの変換

通常、スケール付き FIXED BINARY を使用するとコンパイラーは非効率的なコードを生成するので、使用しないのが最善と言えます。 さらに、スケール付き FIXED BINARY から FIXED DECIMAL に変換する場合、新しいコンパイラーが生成する結果は従来のコンパイラーの結果とは異なる (より正確) 場合があります。

例えば、以下のコードについて見てみましょう。

  dcl i fixed bin(15) init(290);
  dcl s fixed bin(31,16);
  dcl d fixed dec(15,12);

  d = i / 365;
  put skip data( d );
  s = i / 365;
  d = s;
  put skip data( d );

従来のコンパイラーでは、2 つの PUT ステートメントの結果は次のようになります。

   D= 0.794509887700;
   D= 0.794509887700;

新しいコンパイラーでは、2 つの PUT ステートメントの結果は次のようになります。

   D= 0.794509887695;
   D= 0.794509887695;

上記の 2 番目の代入ではスケール付き FIXED BIN から FIXED DEC への変換が明らかに関係していますが、最初の代入にも、式計算の PL/I 規則では式 i / 365 の属性は FIXED BIN(31,16) ですので、そのような変換がかかわっています。

ここで生じていることを理解するには、除算の結果が代入された後の変数 s の内容を考察すると役立ちます。 その後、s は 16 進値 0000CB65 を保持します。 FIXED BIN(31,0) 数値として見ると、値 52069 となりますが、スケール因数 16 があるので、値 52069/2**16 を表します。 この値は、数学的には 52069*5**16/10**16 と等しくなります。 ですから、底 2 から底 10 に変換するには、コンパイラーはこの値を 5**16 (または 152587890625) で乗算します。 そのようにして、スケール因数 16 の FIXED DEC 値が生成されます。ですからスケール因数 12 のターゲット結果を生成するには、最後の 4 桁が除去されます。

電卓で検証できるように 52069 の 5**16 倍は 7945098876953125 で、 新しいコンパイラーで生成される結果では最後の数桁が除去されます。

従来のコンパイラーで生成される結果が異なるのは、生成されるコードが s を 152587890625 ではなく 152587890626 によって乗算するためです。 このようにすると、結果の正確性が低くなります。

この問題を完全に回避するには、小数部の伴う結果が生じる可能性のあるすべての除法を 10 進法で必ず実行するようにします。 これを実行する簡単な方法の 1 つは、DECIMAL 組み込み関数を使用することです。 例えば前述の最初の代入で、式 i / 365 dec(i) / 365 に変更すると、代入の結果は 0.794520547945 となります。

上記のような状況に関して警告するため、コンパイラーはスケール付き FIXED BIN から FIXED DEC への変換を検出すると、メッセージ IBM2810I を発行します。


Terms of use | Feedback

This information center is powered by Eclipse technology. (http://www.eclipse.org)