C# 计算双打最后一位的单位(ULP)

C# 计算双打最后一位的单位(ULP),c#,.net,floating-point,double,C#,.net,Floating Point,Double,NET是否有一个内置的方法来计算给定的双精度或浮点值 如果没有,那么最有效的方法是什么?似乎函数非常简单;这是基于vulkanino链接的问题的公认答案中的伪代码: double value = whatever; long bits = BitConverter.DoubleToInt64Bits(value); double nextValue = BitConverter.Int64BitsToDouble(bits + 1); double result = nextValue - va

NET是否有一个内置的方法来计算给定的双精度或浮点值


如果没有,那么最有效的方法是什么?

似乎函数非常简单;这是基于vulkanino链接的问题的公认答案中的伪代码:

double value = whatever;
long bits = BitConverter.DoubleToInt64Bits(value);
double nextValue = BitConverter.Int64BitsToDouble(bits + 1);
double result = nextValue - value;
对于浮点,您需要提供自己的
singletoint32位
Int32BitsToSingle
实现,因为BitConverter没有这些功能

显示了函数在java实现中的特殊情况;处理这些问题也应该相当简单。

很好,但在负数、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=+/-无穷大)产生一个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 == 0x7FEFFFFFFFFFFFFFL) { // if x == max_double (notice the _E_)
    return BitConverter.Int64BitsToDouble(bits) - BitConverter.Int64BitsToDouble(bits-1);
  }
  double nextValue = BitConverter.Int64BitsToDouble(bits + 1);
  double result = nextValue - fabs(value);
  return result;
}
快乐阅读: