Как проверить в C #, является ли данное двойное число нормальным, т. Е. Не равным нулю, субнормальным, бесконечным или NaN

0

Как проверить С#, если данный двойной номер является нормальным, то есть не равен нулю, субнормальным, бесконечным или NaN.

В C++ существовал метод std :: isnormal, который точно проверял это условие. Есть ли эквивалент в С#?

  • 0
    Что ненормального в нуле ?!
  • 1
    System.Double имеет IsNaN и IsInfinity .
Показать ещё 3 комментария
Теги:
double
std

1 ответ

3
Лучший ответ

Матиас дал базовый подход к обнаружению субнормальных значений в комментарии. Здесь он закодирован:

const long ExponentMask = 0x7FF0000000000000;
static bool IsSubnormal(double v)
{
    long bithack = BitConverter.DoubleToInt64Bits(v);
    if (bithack == 0) return false;
    return (bithack & ExponentMask ) == 0;
}

static bool IsNormal(double v)
{
    long bithack = BitConverter.DoubleToInt64Bits(v);
    bithack &= ExponentMask;
    return (bithack != 0) && (bithack != ExponentMask);
}

И теперь он был протестирован. Тестирование:

static void TestValue(double d)
{
    Console.WriteLine("value is {0}, IsSubnormal returns {1}, IsNormal returns {2}", d, IsSubnormal(d), IsNormal(d));
}

static void TestValueBits(ulong bits)
{
    TestValue(BitConverter.Int64BitsToDouble((long)bits));
}

public static void Main(string[] args)
{
    TestValue(0.0);
    TestValue(1.0);
    TestValue(double.NaN);
    TestValue(double.PositiveInfinity);
    TestValue(double.NegativeInfinity);
    TestValue(double.Epsilon);
    TestValueBits(0xF000000000000000);
    TestValueBits(0x7000000000000000);
    TestValueBits(0xC000000000000000);
    TestValueBits(0x4000000000000000);
    TestValueBits(0xFFF0000000000005);
    TestValueBits(0x7FF0000000000005);
    TestValueBits(0x8010000000000000);
    TestValueBits(0x0010000000000000);
    TestValueBits(0x8001000000000000);
    TestValueBits(0x0001000000000000);
}

Демо: http://rextester.com/DGMCM42070

  • 0
    Это то, чего я ждал! Бен, ты великолепен. Просто чтобы быть на 100% совместимым со ссылкой на C ++ ( en.cppreference.com/w/cpp/numeric/math/isnormal ), IsNormal должен возвращать false для 0, 0.0, Epsilon / 2.0 и всех субнормальных чисел. Не уверены насчет Double.Epsilon?
  • 0
    @SebastianWidz: Если у вас есть тестовый пример, он не проходит, пожалуйста, дайте мне знать. Я исправил ошибку со специальным регистром нуля, поэтому, если вы скопировали первый опубликованный ответ, вам нужно будет IsNormal нулевую тестовую строку из IsNormal .
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню