7

MSDN の記事では、fp:fast モードが有効になっている場合、追加の ID ( a±0.0 = a0.0-a = -a) などの操作は安全ではないことが記載されています。a+0 != aそのようなモードでの例はありますか?

編集:誰かが後述するように、この種の問題は通常、比較を行うときに発生します。私の問題は比較によるもので、疑似コードは次のようになります。

for(i=0;i<v.len;i++)
{
  sum+=v[i];
  if( sum >= threshold) break;
}

0( )の値を追加すると壊れますv[i]v[i]は計算によるものではなく、割り当てられます。v[i]計算によるものである場合、丸めが行われる可能性があることは理解していv[i]ますが、ゼロの値を指定しても、これsum < thresholdがまだ残っているのはなぜsum + v[i] >= thresholdですか?

4

4 に答える 4

1

fp:fast モードが有効になっている場合、追加のアイデンティティ (a±0.0 = a、0.0-a = -a) などの操作は安全ではありません。

その記事が言っていることは

fp:fast モードが有効な場合、次の (安全でない) 代数規則のいずれかがオプティマイザーによって採用される可能性があります。

そして、それは a±0.0 = a と 0.0-a = -a をリストします

fp:fast が有効になっている場合、これらの ID が安全でないと言っているわけではありません。これらの同一性は IEEE 754 浮動小数点演算には当てはまりませんが、/fp:fast はあたかもそれらが正しいかのように最適化されます。

それが falseであることを示す例は確かではありませんa + 0.0 == a(明らかに NaN を除く) が、IEEE 754 には、中間値を切り捨てる必要がある場合など、多くの微妙な点があります。1 つの可能性として、 を含む式がある場合+ 0.0、IEEE 754 では中間値の切り捨てを行う必要があるかもしれませんが、 /fp:fast は切り捨てを行わないコードを生成し、その結果後で結果が生じる可能性があります。 IEEE 754 で厳密に要求されているものとは異なる場合があります。


Pascal Cuoq の情報を使用して、/fp:fast に基づいて異なる出力を生成するプログラムを次に示します。

#include <cmath>
#include <iostream>

int main() {
    volatile double a = -0.0;
    if (_copysign(1.0, a + 0.0) ==  _copysign(1.0, 0.0)) {
        std::cout << "correct IEEE 754 results\n";
    } else {
        std::cout << "result not IEEE 754 conformant\n";
    }
}

/fp:fast を使用してビルドすると、プログラムは「IEEE 754 準拠ではない結果」を出力しますが、/fp:strict を使用してビルドすると、プログラムは「正しい IEEE 754 の結果」を出力します。

于 2013-10-17T19:10:56.177 に答える