x の |x|•10 -8以内にある点を含む区間 [a, b] を計算するには、 a と b を設定します。
double t = fabs(x) * 1e-8;
double a = x-t;
double b = x+t;
丸め誤差により a または b がわずかに不正確になる可能性があるため、これは概算です。間隔にすべてのポイントを絶対に含める場合は、 よりもわずかに高い値を1e-8
使用するか、より高度な手法を使用できます。
いくつかの警告:
テストの一部として間隔を使用して、計算された値が別の値と「ほぼ等しい」かどうかを判断する場合、間隔の大きさを決定するには、使用される浮動小数点演算と関連する値を分析する必要があります。状況によっては、浮動小数点値がゼロから無限大の範囲のエラーを生成する可能性があります。すべての状況で、または「典型的な」状況でさえも有効な許容範囲を 1 つだけ示すことはできません。
間隔の大きさを決定するには、アプリケーションで許容できるエラーを決定する必要があります。計算エラーを許容するために等しくない値を受け入れることは、プログラムが真に等しくない値を等しいものとして受け入れる場合があることを意味します (正確に計算された場合、エラーはありません)。したがって、プログラムが許容できない結果を生成する前に、間隔がどれくらい大きくなるかを把握する必要があります。
明らかに、間隔がそれよりも大きくなければならない場合、プログラムは壊れています。この間隔の使用は機能しません。このような場合、浮動小数点演算を再設計してエラーを少なくするか、プログラムを再設計してこれを回避する必要があります。
一般に、浮動小数点数の表現を使用してその値を読み取ったり変更したりすることはお勧めできません。これを行うには、コンパイラまたはプラットフォームの仕様の詳細に注意を払う必要があります。(特に、テストで動作するように見えるコードは、コンパイラによってサポートされていないという意味で実際には壊れている可能性があり、別のバージョンのコンパイラを使用したり、コンパイル スイッチ (デバッグ用のスイッチやさらに、浮動小数点数の表現にアクセスするためのコードは一般に移植性がありません。(最も顕著なのは、double のバイトを「リトル エンディアン」順で格納するプラットフォームもあれば、「ビッグ エンディアン」順でバイトを格納するプラットフォームもあります。他にも移植性の問題があります。)浮動小数点数、
許容誤差が 10 -8 程度の場合は、 を使用1e-8
して間隔を計算するだけで十分です。つまり、通常の浮動小数点演算を使用でき、浮動小数点数の ULP を計算したり、その表現にアクセスしたりする必要はありません。ただし、IEEE-754 浮動小数点数の ULP を計算したい場合は、この回答のコードを使用してその表現にアクセスせずに計算できます。そのコードはfloat
ではなくのために書かれてdouble
いますが、に変更FLT
しDBL
て、使用する定数を変更できます。float
もちろんにも変更double
。