浮動小数点丸めの処理

デフォルトでは、コンパイラーは、コンパイル時に可能な限り算術演算を実行しようとします。オペランドが定数の浮動小数点演算では、フォールディング が行われます。つまり、算術式の代わりにコンパイル時の結果が表示されます。最適化が使用可能になっている場合には、フォールディングが増大することがあります。ただし、コンパイル時の計算結果は、実行時に計算した場合の結果とわずかに異なる場合があります。これは、コンパイル時には丸め操作がより多く発生するためです。例えば、実行時に乗算/加算融合 (MAF) 演算が使用されて丸めが少なくなるような部分では、コンパイル時に乗算と加算が別々に行われることがあり、その場合は結果にわずかな違いを生じます。

コンパイル時の丸めによる予期しない結果を避けるには、次の 2 つの方法があります。

例えば、次のコード例を -yz (丸めモードを切り捨てに指定するコマンド) でコンパイルすると、 u.x の 2 つの結果は少し違うものになります。

int main ()
 {
  union uu
   {
    float x;
    int i;
    } u;
 
    volatile float one, three;
 
    u.x=1.0/3.0;
    printf("1/3=%8X ¥n", u.i);
 
    one=1.0;
    three=3.0;
    u.x=one/three;
    printf ("1/3=%8X ¥n", u.i);
    return 0;
 }

これは、1.0/3.0 の計算が、コンパイル時には切り捨てによってフォールディングされるのに対して、実行時には one/three がデフォルトの最近値への丸めモードで計算されるためです。 (変数 one および threevolatile と宣言することで、最適化を行っても、コンパイラーによるフォールディングは抑制されます。)このプログラムの出力は、次のようになります。

   1/3=3EAAAAAA
   1/3=3EAAAAAB

この例でコンパイル時の結果と実行時の結果に整合性を持たせるためには、オプション -yn (これがデフォルトです) を指定してコンパイルします。 IBM Copyright 2003