8

私はいくつかの浮動小数点計算を行っていますが、結果は私が望むほど正確ではありません。

これはアルゴリズムです:

..。
センター=(max_x + min_x)/ 2
距離=old_x-中心
new_x =中心+(距離*係数)

new_xを返します

min_x、max_x、およびold_xはすべてfloatです。最大値と最小値の平均をとると、最大の誤差が発生し、誤差に係数(浮動小数点数の場合もあります)が掛けられると思います。

new_xが可能な限り正確になるように、FP計算によるエラーを最小限に抑えるにはどうすればよいですか?

4

5 に答える 5

4

old_xcenterが近い場合、精度が失われます。

それは意味の喪失と呼ばれる

最終的に減算が行われるように計算を変更できます。

center = (max_x + min_x) / 2
new_x = (center + (old_x * factor)) - (center * factor)
于 2011-06-24T17:26:14.803 に答える
2

言語によっては、Python の decimalJava の BigDecimalなど、使用できる固定/任意精度の数値型が存在する可能性があります。

于 2011-06-24T17:25:09.730 に答える
1

Yochai が言うように、あなたの問題はおそらく減算によって引き起こされますold_x - centerold_xcenterが互いに近い場合、精度が失われます。

double簡単な解決策は、代わりに を使用して計算を行うことfloatですが、それは不可能だと思います。その場合、減算を取り除く必要があります。1つの可能性は

distance_max = max_x - center
distance_min = min_x - center
distance = (distance_max + distance_min) / 2
new_x = center + factor * distance

max_xこれは、min_xcenterがかなり離れていて、 と の平均がmax_xmin_x近い場合に役立ちますcentermax_xそれでも解決しない場合は、実際に計算できるように の計算を適応させることができますがmax_x - center、表示されていない部分を変更する必要があります。

于 2011-06-25T12:36:13.197 に答える
1

これにより、元のアルゴリズムから少なくとも 1 つのエラーの原因が取り除かれます。

# Adding min and max can produce a value of larger magnitude, losing some low-order bits
center = min_x + (max_x - min_x)/2
distance = old_x - center
new_x = center + (distance * factor)

return new_x

との関係についてより多くの知識があればold_x、おそらくこれよりもうまくいくでしょう。min_xmax_x

于 2011-06-24T22:22:19.250 に答える
1

以前の実装はすべて丸めを使用していないため、大きなエラーが発生します。固定小数点演算でこれを行う方法は次のとおりです。X.1u prevision を使用しています (小数部分に 1 LSB を使用)。

//center = (max_x + min_x) / 2
center = max_x + min_x // zero error here

// distance = old_x - center
distance = (old_x << 1) - center // zero error here

//new_x = center + (distance * factor)
new_x = (**1** + center + (distance * factor)) >> 1

return new_x

factor が固定小数点 (整数) であり、N ビットが分数を表す場合、new_x は次のように計算できます。

new_x = ( (1 << N) + (center << N) + (distance * factor) ) >> (N + 1)
  • (center << N)は N+1 個の小数ビットを持ちます
  • 距離 * 係数には N+1 個の小数ビットがあります
  • (1 << N)は、上記の固定小数点精度で1 << (N+1)が「1」であるため、「半分」です。

各部分を理解したら、上記の行を圧縮できます。

new_x = ( ((1 + center) << N) + (distance * factor) ) >> (N + 1)

もちろん、使用される整数型は十分に大きくなければなりません。有効な範囲が不明な場合は、この関数への入力と他の何かを確認する必要があります。ほとんどの場合、これは必要ありません。

これは、固定小数点演算と同じくらい優れています。これは、ハードウェア回路が整数演算を実行する方法です。

于 2013-11-26T08:29:23.410 に答える