出于测试中的边界值分析的目的,我一直在寻找在.Net中获得双精度或浮点数的最小步长。这将允许我获得下一个较大的和下一个较小的值,可以用double或float表示。
double.epsilon,"仅适用于值为零或指数为-1022"的双实例。
让我们说我有一个任意的双重或浮动。我可以在.Net中代表的下一个更大和下一个更小的值是什么?
根据MSDN文章,我实现了以下代码,看起来似乎有道理:
private static int GetExponentWithMinorAdjustment(double value)
{
//int indent = result.Length;
// Convert the double to an 8-byte array.
byte[] bytes = BitConverter.GetBytes(value);
int exponent = (bytes[7] & 0x07F) << 4;
exponent = exponent | ((bytes[6] & 0xF0) >> 4);
int adjustment = exponent != 0 ? 1023 : 1022;
return exponent != 0 ? exponent - 1 : exponent; ;
}
private static double NextLargerNumber(double value)
{
// Cannot use double.epsilon * Math.Pow(2, GetExponentWithMinorAdjustment(value)) as this results in infinity
return value + Math.Pow(2, GetExponentWithMinorAdjustment(value) - 1074));
}
上述代码的问题在于它看起来很不稳定。注意三元运算符(灵感来自MSDN文章);这种调整的目的是什么?
此外,虽然几个测试的输出对于正双精度值看起来没问题,但负值的结果似乎不太好(参见输出图像):
这个问题的可接受,正确和理想的解决方案是什么样的?
答案 0 :(得分:1)
使用不安全代码将位直接映射到unsigned int,递增或递减,转换回来。
可能需要在0的边界处进行额外的特殊处理,以及无穷大,Nan等的特殊值。