6

double が等しいかどうかを比較する場合、浮動小数点計算でエラーが発生する可能性があるため、許容レベルを指定する必要があります。例えば:

double x; 
double y; 
x = f();
y = g();

if (fabs(x-y)<epsilon) {
   // they are equal!
} else {
   // they are not!
}

ただし、計算を行わずに定数値を代入した場合でも、イプシロンをチェックする必要がありますか?

double x = 1;
double y = 1;

if (x==y) {
   // they are equal!
} else {
   // no they are not!
}

比較は==十分ですか?それともやり直す必要がありfabs(x-y)<epsilonますか?割り当てにエラーを導入することは可能ですか? 私は偏執的すぎますか?

キャスト ( double x = static_cast<double>(100)) はどうですか? 浮動小数点エラーも発生しますか?

LinuxでC++を使用していますが、言語によって異なる場合は、それも理解していただきたいです。

4

5 に答える 5

3

実際には、値と実装に依存します。C++ 標準 (ドラフト n3126) には、次のように書かれてい2.14.4 Floating literalsます。

スケーリングされた値がその型の表現可能な値の範囲内にある場合、結果は、表現可能な場合はスケーリングされた値になり、そうでない場合は、実装定義の方法で選択されたスケーリングされた値に最も近い、より大きなまたはより小さな表現可能な値になります。

言い換えれば、値が正確に表現可能である場合 (そして1、IEEE754 では100静的キャストと同様に表現可能である場合)、値を取得します。それ以外の場合 ( など0.1)、実装定義の近似一致(a)が得られます。今、同じ入力トークンに基づいて別の近似一致を選択した実装について非常に心配しています、可能です。


(a)実際には、その段落は 2 つの方法で読むことができます。実装は、実際に最も近い値に関係なく、最も近い高い値または最も近い低い値を自由に選択するか、目的の値に最も近い値を選択する必要があります。

後者の場合、この答えは変わりません。ただし、表現可能な 2 つの型のちょうど中間点に浮動小数点値をハードコードするだけでよく、実装ではどちらかを自由に選択できます。

たとえば、バンカーの丸めが適用されるのと同じ理由で、累積誤差を減らすために、次に高いものと次に低いものを交互に繰り返すことがあります。

于 2012-03-23T05:36:59.077 に答える
0

いいえ、リテラルを割り当てる場合、それらは同じである必要があります:)

また、同じ値から始めて同じ操作を行う場合、それらは同じである必要があります。

浮動小数点値は正確ではありませんが、操作によって一貫した結果が得られるはずです:)

于 2012-03-23T04:49:43.800 に答える
0

どちらの場合も、最終的に実装定義の表現に従います。

浮動小数点値の格納とその表現は多くの形式を取ります - アドレスまたは定数でロードしますか? 高速数学によって最適化されていますか? レジスタ幅は?SSEレジスタに格納されていますか?多くのバリエーションが存在します。

正確な動作と移植性が必要な場合は、この実装定義の動作に依存しないでください。

于 2012-03-23T05:57:43.193 に答える
0

簡単な答え: 定数の場合 == は問題ありません。注意すべき例外が2 つあります。

最初の例外:

0.0 == -0.0

IEEE 754 標準と同等の負のゼロがあります。これは、f(x) == f(y) => x == y を破る 1/INFINITY == 1/-INFINITY を意味します。

2 番目の例外:

NaN != NaN

これは NotaNumber の特別な注意点であり、テスト機能を利用できないシステムで数値が NaN であるかどうかを調べることができます (はい、発生します)。

于 2012-03-23T17:21:42.833 に答える
0

従う浮動小数点数の標準的な一般的な実装である IEEE-754 では、無限に正確な結果に最も近い表現可能な値である結果を生成する浮動小数点演算が必要です。したがって、直面する唯一の不正確さは、実行する各操作の後の丸めと、チェーンの前に実行された操作からの丸め誤差の伝播です。フロート自体は不正確ではありません。ところで、イプシロンは計算可能であり、計算する必要があります。これについては、数値に関する本を参照してください。

浮動小数点数は、仮数の長さまで正確に整数を表すことができます。たとえば、int から double にキャストする場合、常に正確になりますが、float にキャストする場合、非常に大きな整数に対して正確ではなくなります。

整数の代用として浮動小数点数を広範囲に使用する主な例が 1 つあります。これは、組み込み型の整数を持たない LUA スクリプト言語であり、浮動小数点数はロジックやフロー制御などに広く使用されています。パフォーマンスまた、浮動小数点数を使用することによるストレージのペナルティは、実行時に複数の型を解決するペナルティよりも小さいことが判明し、実装が軽くなります。LUA は PC だけでなく、ゲーム機でも広く使用されています。

現在、多くのコンパイラには、IEEE-754 互換性を無効にするオプションのスイッチがあります。その後、妥協が行われます。非正規化数 (指数が可能な最小値に達した非常に小さな数) は、多くの場合ゼロとして扱われ、累乗、対数、平方根、および 1/(x^2) の実装で近似を行うことができますが、加算/減算、比較と乗算は、正確に表現できる数値のプロパティを保持する必要があります。

于 2012-03-23T06:05:42.433 に答える