извлекая мантиссу и показатель степени из двойного в c # - PullRequest
26 голосов
/ 23 декабря 2008

Есть ли какой-нибудь простой способ получить мантиссу и показатель степени от двойного в c # (или .NET в целом)?

Я нашел этот пример с помощью Google, но я не уверен, насколько надежным он будет. Может ли двоичное представление для двойного изменения в какой-то будущей версии фреймворка и т. Д.

Другой альтернативой, которую я нашел, было использование System.Decimal вместо double и использование метода Decimal.GetBits () для их извлечения.

Есть предложения?

Ответы [ 2 ]

28 голосов
/ 24 декабря 2008

Бинарный формат не должен изменяться - это, безусловно, будет серьезным изменением существующих спецификаций. Он определен в формате IEEE754 / IEC 60559: 1989, как сказал Джимми. (Раздел 1.3 спецификации языка C # 3.0; раздел 8.2.2 ECMA 335). Код в DoubleConverter должен быть хорошим и надежным.

Для справки в будущем соответствующий бит кода в примере:

public static string ToExactString (double d)
{
    …

    // Translate the double into sign, exponent and mantissa.
    long bits = BitConverter.DoubleToInt64Bits(d);
    // Note that the shift is sign-extended, hence the test against -1 not 1
    bool negative = (bits & (1L << 63)) != 0;
    int exponent = (int) ((bits >> 52) & 0x7ffL);
    long mantissa = bits & 0xfffffffffffffL;

    // Subnormal numbers; exponent is effectively one higher,
    // but there's no extra normalisation bit in the mantissa
    if (exponent==0)
    {
        exponent++;
    }
    // Normal numbers; leave exponent as it is but add extra
    // bit to the front of the mantissa
    else
    {
        mantissa = mantissa | (1L << 52);
    }

    // Bias the exponent. It's actually biased by 1023, but we're
    // treating the mantissa as m.0 rather than 0.m, so we need
    // to subtract another 52 from it.
    exponent -= 1075;

    if (mantissa == 0) 
    {
        return negative ? "-0" : "0";
    }

    /* Normalize */
    while((mantissa & 1) == 0) 
    {    /*  i.e., Mantissa is even */
        mantissa >>= 1;
        exponent++;
    }

    …
}

В то время комментарии имели смысл для меня, но я уверен, что сейчас мне придется немного подумать о них. После первой части у вас есть «сырой» показатель степени и мантисса - остальная часть кода просто помогает обработать их более простым способом.

1 голос
/ 23 декабря 2008

Представление является стандартом IEEE и не должно изменяться.

https://msdn.microsoft.com/en-us/library/system.double(v=vs.110).aspx

Тип Double соответствует стандарту IEC 60559: 1989 (IEEE 754) для двоичной арифметики с плавающей точкой.

РЕДАКТИРОВАТЬ: причина, почему десятичная дробь имеет getBits и двойной нет, состоит в том, что десятичная дробь сохраняет значащие цифры. 3,0000 м == 3,00 м, но показатели / мантиссы на самом деле разные. Я думаю, что числа с плавающей запятой / двойники представлены уникально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...