获得(非零)double或float

时间:2016-05-08 22:13:58

标签: c# .net floating-point precision

出于测试中的边界值分析的目的,我一直在寻找在.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文章);这种调整的目的是什么?

此外,虽然几个测试的输出对于正双精度值看起来没问题,但负值的结果似乎不太好(参见输出图像): Program Output

这个问题的可接受,正确和理想的解决方案是什么样的?

1 个答案:

答案 0 :(得分:1)

使用不安全代码将位直接映射到unsigned int,递增或递减,转换回来。

可能需要在0的边界处进行额外的特殊处理,以及无穷大,Nan等的特殊值。