C# 计算双打最后一位的单位(ULP)
NET是否有一个内置的方法来计算给定的双精度或浮点值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
如果没有,那么最有效的方法是什么?似乎函数非常简单;这是基于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;
}
快乐阅读: