2012-02-28 5 views
6

.NETには、与えられたdoubleまたはfloatのULPを計算する組み込みメソッドがありますか?ダブルスの最後の場所(ULP)の単位を計算する

そうでない場合は、これを行う最も効率的な方法は何ですか?

+0

幸せな読書:http://stackoverflow.com/questions/1668183/find-min-max-of-a-float-double-that-has-the-same-internal-representation – vulkanino

答えて

4

これは機能がかなり些細なものだと思われます。これはvulkaninoで結ば質問への受け入れ答えに擬似コードに基づいています:山車のために

double value = whatever; 
long bits = BitConverter.DoubleToInt64Bits(value); 
double nextValue = BitConverter.Int64BitsToDouble(bits + 1); 
double result = nextValue - value; 

BitConverterは、これらの機能を持っていないので、あなたは、SingleToInt32BitsInt32BitsToSingleの独自の実装を提供する必要があると思います。

This pageは、関数のjava実装における特殊なケースを示しています。それらを扱うこともかなり簡単です。

1

phoogの回答は良いですが、負数、max_double、無限大、NaNの弱点があります。

phoog_ULP(正のx) - >正の数です。良い。
phoog_ULP(負のx) - >負の数です。私は正の数を期待する。私が代わりにお勧めします。この問題を解決するには
:あなたが気にしなければならない

以下
long bits = BitConverter.DoubleToInt64Bits(value) & 0x7FFFFFFFFFFFFFFFL; 

解像度を必要とするフリンジ例です...

phoog_ULP(X = +/- Max_double 1.797 ... E + 308)が戻ります無限の結果(+1.996 ... e + 292)が予想される。
phoog_ULP(x = +/- Infinity)はNaNになります。 +無限大が予想される。
phoog_ULP(x = +/- NaN)が予期せずsNanからqNaNに変わることがあります。変化は期待されない。この場合、符号が+になるべきであるかどうかを議論することができます。

これらを解決するために、私は便宜のために "ビット"値で可能なbrutish if()テストにしか対応していません。例:

double ulpc(double value) { 
    long long bits = BitConverter::DoubleToInt64Bits(value); 
    if ((bits & 0x7FF0000000000000L) == 0x7FF0000000000000L) { // if x is not finite 
    if (bits & 0x000FFFFFFFFFFFFFL) { // if x is a NaN 
     return value; // I did not force the sign bit here with NaNs. 
     } 
    return BitConverter.Int64BitsToDouble(0x7FF0000000000000L); // Positive Infinity; 
    } 
    bits &= 0x7FFFFFFFFFFFFFFFL; // make positive 
    if (bits == 0x7FEFFFFFFFFFFFFL) { // if x == max_double (notice the _E_) 
    return BitConverter.Int64BitsToDouble(bits) - BitConverter.Int64BitsToDouble(bits - 1); 
    } 
    double nextValue = BitConverter.Int64BitsToDouble(bits + 1); 
    double result = nextValue - value; 
} 
関連する問題