Search code examples
c#.net-corefloating-pointdoublesubnormal-numbers

Why does .NET say that subnormal numbers are never powers of 2?


Since .NET 7 (from 2022), there has been a static method double.IsPow2.

Who decided it should never consider subnormal numbers as powers of 2? For example, if I try this code:

double exp = -1000.0;
while (true)
{
    double pow2 = double.Exp2(exp);
    if (pow2 == 0.0)
    {
        break;
    }
    bool isOk = double.IsPow2(pow2);
    Console.WriteLine($"{exp} {isOk}");
    --exp;
}

it produces output like:

...
-1020 True
-1021 True
-1022 True
-1023 False
-1024 False
-1025 False
...

So a number like Exp2(-1024.0) (a.k.a. Pow(2.0, -1024.0) or 5.562684646268003E-309) is not allowed as a power of 2. But it seems it could be useful; for example, the eleven numbers:

Exp2(-1024.0), Exp2(-1024.1), Exp2(-1024.2), Exp2(-1024.3), ..., Exp2(-1025.0)

are all different, but the first one and the last one are "more" powers of 2 than the other nine ones are?


Solution

  • This was a bug reported here and fixed by this commit.

    Note that the commit shows that some tests were wrong, i.e. it was previously assumed that IsPow2 should not return true on subnormals.