質問

.NETのいくつかの地理的座標を扱う方法があり、座標ペアを保存する構造体があります。約255.99999998が計算されるため、構造体に保存されます。 toString()で印刷されると、256になります。これは起こりません-256は0である必要があります。255.9999998を印刷しても気にしませんが、デバッガーが255.99999998が問題であることを示すときに256を印刷します。保存とディスプレイ0の両方を使用すると、さらに優れています。

具体的には、比較の問題があります。 255.99999998は256に十分に近いため、等しくなります。ダブルを比較するときはどうすればよいですか?ある種のイプシロン価値を使用しますか?


編集:具体的には、私の問題は、値を取得し、いくつかの計算を実行し、その数の逆の計算を実行し、元の値を正確に取り戻す必要があることです。

役に立ちましたか?

解決

Epsilonアプローチを使用することもできますが、Epsilonは通常、Floating-Point Arithmeticが喪失しているという事実を回避するためのファッジです。

バイナリフローティングポイントを完全に回避し、優れた合理的なクラスを使用することを検討する場合があります。

上記の計算は、合理的なタイプで得られるようにロスレス算術をしている場合、おそらく256になるように運命づけられていました。

合理的なタイプは、比率または分数クラスの名前で移動でき、書くのはかなり簡単です

これが1つです 。これがそうです


編集....

あなたの問題を理解するために、小数値0.01がバイナリ表現に変換されると、有限メモリに正確に保存できないことを考慮してください。この値の16進表現は0.028F5C28F5Cで、「28F5C」が無限に繰り返されます。したがって、計算を行う前でさえ、0.01をバイナリ形式で保存するだけで正確さを失います。

合理的および10進数クラスは、パフォーマンスコストではあるが、この問題を克服するために使用されます。合理的なタイプあなたの価値を表すために分子と分母を保存することにより、この問題を避けます。小数タイプは、バイナリエンコードされた小数を使用します フォーマット, 、分割では損失がありますが、一般的な小数値を正確に保存できます。

あなたの目的のために、私はまだ合理的なタイプを提案します。

他のヒント

これは、数字がどのように保存されるかではなく、どのように印刷されるかに関する問題のように聞こえます。 a double 約15の重要な数字があるため、256から255.99999998を正確に余裕を持って伝えることができます。

フォーマット文字列を選択できます。この文字列は、好きなだけの数字を表示できるようにする必要があります。

平等のダブルを比較する通常の方法は、それらを差し引き、絶対値が事前定義されたエプシロン、おそらく0.000001よりも少ないかどうかを確認することです。

2つの値が等しいしきい値で自分自身を決定する必要があります。これは、いわゆる使用に相当します 固定点番号 (浮動点とは対照的に)。その後、手動でラウンドアップを実行する必要があります。

既知のサイズ(UINT32またはUINT64が利用可能な場合は、.NETがわからない場合)の符号なしタイプを使用して、固定点番号タイプMOD 256として扱います。

例えば。

typedef uint32 fixed;

inline fixed to_fixed(double d)
{
    return (fixed)(fmod(d, 256.) * (double)(1 << 24))
}

inline double to_double(fixed f)
{
    return (double)f / (double)(1 << 24);
}

または、丸めの慣習に合わせてより詳述されたもの(最も近く、低く、より高い、奇妙な、偶数)。固定された最高8ビットは整数部を保持し、24の低いビットは分数部分を保持します。絶対精度は2^{-24}です。

そのような数値を追加して覆すことは、自然に256で包み込まれていることに注意してください。乗算には注意する必要があります。

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