質問

コード内のバグを見つけようとして 1 時間努力した後、ついにその理由が見つかりました。1fに非常に小さなフロートを追加しようとしましたが、何も起こりませんでした。理由を理解しようとしていたところ、その小さな float を 0f に追加すると完璧に機能することがわかりました。

なぜこうなった?これは「桁違い」と関係があるのでしょうか?この問題に対する回避策はありますか?

前もって感謝します。

編集:

現時点では、倍精度または 10 進数への変更はオプションではありません。

役に立ちましたか?

解決

単精度 (32 ビット) 浮動小数点値の精度は小数点以下約 7 桁であるためです。つまり、追加する値は、少なくとも次の値に追加した場合、実質的にゼロになります。 1. 。ただし、この場合は指数が小さいため、値自体は簡単に float に格納できます。しかし、それを正常に追加するには 1 大きい方の数値の指数を使用する必要があります...そしてゼロ以降の数字は四捨五入で消えます。

使用できます double より正確な精度が必要な場合。パフォーマンスの点では、今日のハードウェアではこれに違いはありませんし、メモリもすべての変数について考慮する必要があるほど制約されていないことがよくあります。

編集: あなたが使用すると述べたように、 double 使用できるオプションではありません カハンの合計, 、 として アクーン コメントで指摘されました。

別のオプションとして、中間計算を倍精度で実行し、その後にキャストすることもできます。 float また。ただし、これは、大きな数値に非常に小さな数値を加算するだけではなく、さらにいくつかの演算がある場合にのみ役立ちます。

他のヒント

フロート精度の桁数が一定であるので、これはおそらく起こるが、指数は明らかに変化することができる。

これは、あなたが0にあなたの小さな数を追加することができますが、あなただけの精密左の十分な数字がないので、0から異なる指数を持っている数にそれを追加することを期待できないことを意味します。

あなたはすべてのコンピュータ科学者は、浮動小数点演算<について知っておくべきことをお読みください/>。

それは浮動小数点精度とは何かを持っているように、

に見えます。私があなただったら、私はdecimalのように、異なるタイプを使用すると思います。それは、高精度のエラーを修正する必要があります。

受け入れられた回答に加えて、次のようになります。 多数の小さな数値といくつかの大きな数値を合計する必要がある場合は、次を使用する必要があります。 カハンの合計.

(あなたがdoubleを使用することができないため)

は、パフォーマンスが問題である場合は、バイナリスケーリング/固定小数点ポイントにはオプションかもしれません。 floatsは整数として格納されているが、多数(例えば、2 ^ 16)によってスケーリングされます。中間演算は(比較的速い)整数演算を用いて行われます。最終的な答えは、スケーリング係数で割ることによって、端部で浮動小数点に変換することができる。

ターゲットプロセッサは、ハードウェア浮動小数点ユニットを欠いている場合は、

これはしばしば行われます。

あなたは代わりにdoubleのこれらの山車を行いますあなたのリテラル、上のFサフィックスを使用しています。だからあなたの非常に小さなフロートは大きなフロートに消えます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top