2012-02-28 65 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; 
}