Подтвердить что ты не робот

Извлечение мантиссы и экспонента из двойного в С#

Есть ли простой способ получить мантиссы и экспонента из double в С# (или вообще .NET)?

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

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

Любые предложения?

4b9b3361

Ответ 1

Бинарный формат не должен меняться - это, безусловно, будет нарушением существующих спецификаций. Он определен в формате IEEE754/IEC 60559: 1989, как сказал Джимми. (Раздел 1.3 спецификаций языка С# 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 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 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++;
    }

    …
}

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

Ответ 2

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

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

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

EDIT: причина, по которой десятичный код имеет getBits, а double - это не то, что десятичная запятая сохраняет значимые цифры. 3.0000m == 3.00m, но экспоненты/мантиссы на самом деле разные. Я думаю, что floats/doubles однозначно представлены.