3

計算中に精度を維持するために float 値を 10 倍にスケーリングすると、常に正確になりますか?

この質問は、関係する数より小さいかより大きい場合Math.pow (2,53)にのみ適用されます。Math.pow (10,-15)Math.pow (10,16 ) > Math.pow (2,53)

これでいくつかの点が明確になることを願っています

0.3 - 0.2 //0.09999999999999998

明らかに不正確です

しかし、スケーリングされた数値で減算を行う

var a = 0.3;
var b = 0.2;

var l = Math.max ("".split.call(a,".")[1].length,"".split.call(b,".")[1].length);

var c;

a *= Math.pow (10,l);
b *= Math.pow (10,l);

c = a-b;

c /= Math.pow(10,l);

console.log(c); //0.1

正確 な 結果が得られます。

質問は、上記の基準に一致する float 値はありますかf<Math.pow(10,-15)? 10 のべき乗(ここでMath.pow ( 10 , n<16)<Math.pow(2,53))を掛ける、N(b)-N(a)にならない? 10の累乗?double value nearest

上記のスニペットで説明したように。

これは単なる興味の問題であり、実際の計算にこれを使用することについてではありません。ただ興味があります

誤解を恐れずに言います この説明は苦手です

4

1 に答える 1

1

質問の意図がずれていると思います。

2 進浮動小数点値 a と b が数桁の 10 進数に非常に近いことがわかっている場合、これらの値に 10 の累乗を掛け、減算し、10 の累乗で除算しても、通常はより良い結果が得られません。単純に値を直接減算するよりも優れています。掛け算と割り算のそれぞれで丸め誤差が発生することが多く、a と b を直接減算するよりも最終結果の精度が低くなる傾向があります。したがって、このラウンドアバウト方式を使用しても何も得られません。

a と b にはすでにいくつかの丸め誤差があるため (それらは正確に近い数値ではなく、表現したい数値です)、計算された値b-aが、 10 進数 (ただし、最大 1 ULP 離れています)。まれに、迂回した計算での丸め誤差の組み合わせによって、その差に近い結果が得られることがありますが、これは設計というよりは偶然 (実質的に偶然) の問題です。

含まれる 10 のべき乗 p がわかればMath.round((b-a)*p)/p、 の丸め誤差(b-a)*pが常に 0.5 未満になるように含まれる数が十分に小さい場合、 を計算することでこの可能な限り最良の結果を得ることができます。

とにかく、どちらのアプローチも計算を設計するのに適した方法ではない可能性があります。

Edit3 について: 2 53未満の 10 の非負のべき乗はすべて正確に表現できます。適切powに実装すると、これらのケースに対して正確な結果が返されます。最下位ビット セットの値が 2 –dである double x を考えます。この double を掛けたときに整数になる最小の 10 の累乗は 10 dです。10 dが 2 53未満で、10 d •x が 2 53未満の場合、両方とも正確に表現可能です。次に、浮動小数点演算の IEEE-754 仕様により、10 dと x の積は正確です。

于 2013-05-23T18:01:02.060 に答える