2つのfloat値(fLow
およびfHigh
)が与えられた場合、2つの連続する値の間の最大または最大のストライド/ギャップをどのように計算できますか?
例えば:
値は事実上最も近い2に丸められる16777217f
ため20000000f
、答えの範囲は、になります。2
これを任意の範囲に一般化すると、頭を悩ませることになります-何か提案はありますか?
乾杯、
これは言語に依存しないはずですが、私はC#を使用しています(これはIEEE-754に準拠していると思います)。
2つのfloat値(fLow
およびfHigh
)が与えられた場合、2つの連続する値の間の最大または最大のストライド/ギャップをどのように計算できますか?
例えば:
値は事実上最も近い2に丸められる16777217f
ため20000000f
、答えの範囲は、になります。2
これを任意の範囲に一般化すると、頭を悩ませることになります-何か提案はありますか?
乾杯、
これは言語に依存しないはずですが、私はC#を使用しています(これはIEEE-754に準拠していると思います)。
これはCです。丸めなどのために、IEEE754の動作が必要です。IEEE 754 64ビットバイナリ(double
)の場合、SmallestPositive
2 -1074、約4.9406564584124654417656879286822137236505980261e-324、DBL_EPSILONは2 -52、2.220446049250313080847263336181640625e -16です。32ビットバイナリ(float
)の場合は、表示される場所に変更します(DBL
これらの変更なしで機能するはずですが、に変更します)。次に、2 -149、約1.401298464324817070923729583289916131280261941876515771757068283889791e-45、FLT_EPSILONは2 -23、1.192028955078125e -07です。FLT
double
float
fabs
fabsf
fmax
fmaxf
SmallestPositive
2つの値の間の間隔の場合、最大のステップサイズは、もちろん、より大きな大きさの端点でのステップサイズです。(そのエンドポイントが正確に2の累乗である場合、そのポイントから次のポイントまでのステップサイズは間隔自体に表示されないため、これは特殊なケースになります。)
#include <float.h>
#include <math.h>
/* Return the ULP of q.
This was inspired by Algorithm 3.5 in Siegfried M. Rump, Takeshi Ogita, and
Shin'ichi Oishi, "Accurate Floating-Point Summation", _Technical Report
05.12_, Faculty for Information and Communication Sciences, Hamburg
University of Technology, November 13, 2005.
*/
double ULP(double q)
{
// SmallestPositive is the smallest positive floating-point number.
static const double SmallestPositive = DBL_EPSILON * DBL_MIN;
/* Scale is .75 ULP, so multiplying it by any significand in [1, 2) yields
something in [.75 ULP, 1.5 ULP) (even with rounding).
*/
static const double Scale = 0.75 * DBL_EPSILON;
q = fabs(q);
return fmax(SmallestPositive, q - (q - q * Scale));
}
さて、マシンの精度は、その名前が示すように、実際には一般的にマシン、さらにはコンパイラに依存する可能性のあるものです。したがって、実際に確認するには、通常、実際に何が起こっているかをテストするプログラムを作成する必要があります。
ただし、特定の間隔で最大距離を概算するために使用できる便利な数式を実際に探しているのではないかと思います。マシンイプシロンに関するウィキペディアの記事は、このトピックに関する非常に優れた概要を示しています。以下では、このソースから引用しています。
浮動小数点表現の計算機イプシロン(つまり、標準の浮動小数点の場合は約2 ^(-24))とすると、正規化された数とその近傍とs
の間の最大間隔はです。正規化という言葉はここでは非常に重要であり、正規化されていない数値の状況を考慮しようとはしません。これは、物事が本当に厄介になる場所だからです...x
2*s*|x|
つまり、特定のケースでは、h
提案する間隔の最大間隔はで与えられh = 2*s*max(|fLow|, |fHigh|)
ます。