9

私のマシンの浮動小数点数の内部表現の結果であると思われる精度の問題を克服する方法があるかどうか疑問に思いました。

わかりやすくするために、問題は次のように要約されます。

// str is "4.600";   atof( str ) is 4.5999999999999996  
double mw = atof( str )  

// The variables used in the columns calculation below are:   
//  
//                    mw = 4.5999999999999996  
//                    p = 0.2  
//                    g = 0.2  
//                    h = 1 (integer)  

int columns = (int) ( ( mw - ( h * 11 * p ) ) / ( ( h * 11 * p ) + g ) ) + 1;

整数型にキャストする前の列計算の結果は1.9999999999999996です。2.0の望ましい結果からはまだ近いです。

どんな提案でも大歓迎です。

4

8 に答える 8

15

浮動小数点演算を使用する場合、厳密な等価性はほとんど意味がありません。通常、許容値の範囲と比較します。

一部の値は、浮動小数点値として正確に表現できないことに注意してください。

すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと浮動小数点数の比較を参照してください。

于 2009-02-26T14:48:03.257 に答える
12

精度問題ありません。

得られた結果 (1.9999999999999996) は、数学的な結果 (2) と 1E-16 の差がありました。入力「4.600」を考慮すると、これは非常に正確です。

もちろん、丸めの問題があります。C++ のデフォルトの丸めは切り捨てです。キップのソリューションに似たものが必要です。詳細は正確なドメインによって異なりますround(-x)== - round(x)

于 2009-02-26T15:31:56.100 に答える
10

まだ読んでいない場合、この論文のタイトルは本当に正しいです。最新のコンピューターでの浮動小数点演算の基礎、いくつかの落とし穴、および浮動小数点演算がそのように動作する理由についての説明について詳しく知るために、これを読むことを検討してください。

于 2009-02-26T14:47:23.180 に答える
5

浮動小数点数を整数に丸める非常に簡単で効果的な方法:

int rounded = (int)(f + 0.5);

注: これfは が常に正の場合にのみ機能します。(jランダムハッカーに感謝)

于 2009-02-26T14:57:11.490 に答える
3

コンピューターでは、浮動小数点数は決して正確ではありません。それらは常に近似値にすぎません。(1e-16が近いです。)

見えない隠れた部分があることもあります。a*b != b*a のように、代数の基本的なルールが適用されなくなることがあります。レジスタとメモリを比較すると、これらの微妙な違いが明らかになることがあります。または、数学コプロセッサとランタイム浮動小数点ライブラリを使用します。(私はこれをあまりにも長くやっています。)

C99 の定義: ( math.hを参照)

double round(double x);
float roundf(float x);
long double roundl(long double x);

.

または、自分でロールすることもできます:

template<class TYPE> inline int ROUND(const TYPE & x)
{ return int( (x > 0) ? (x + 0.5) : (x - 0.5) ); }

浮動小数点の同等性については、次を試してください。

template<class TYPE> inline TYPE ABS(const TYPE & t)
{ return t>=0 ? t : - t; }

template<class TYPE> inline bool FLOAT_EQUIVALENT(
    const TYPE & x, const TYPE & y, const TYPE & epsilon )
{ return ABS(x-y) < epsilon; }
于 2009-02-26T16:36:17.630 に答える
2

小数を使用:decNumber ++

于 2009-02-26T14:41:29.013 に答える
2

この論文を読んで、探しているものを見つけることができます。

ここに示すように、結果の絶対値を取得できます。

x = 0.2;  
y = 0.3;  
equal = (Math.abs(x - y) < 0.000001)  
于 2009-02-26T14:43:25.687 に答える