2012-02-28 64 views

回答

4

看起來這個功能很瑣碎;這是基於在接受答案的僞代碼由vulkanino鏈接的問題:

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

對於花車,你需要提供自己的執行SingleToInt32BitsInt32BitsToSingle,因爲BitConverter不具備這些功能。

This page顯示java函數中的特例;處理這些應該也是相當微不足道的。

1

phoog答案很好,但有負數,max_double,infinity和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。預期沒有變化。在這種情況下,如果符號應該變成+,那麼可以以任何方式爭論。

爲了解決這些問題,我只能看到一系列簡短的if()測試來適應這些,爲了方便起見,可能使用「bits」值。例如:

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; 
}