.net 在c#中提取双精度浮点数的尾数和指数

lhcgjxsq  于 2023-01-22  发布在  .NET
关注(0)|答案(2)|浏览(235)

在c#(或一般的.NET)中,有没有直接的方法从一个double得到尾数和指数?
我在Google上找到了this example,但是我不确定它的健壮性有多强。在将来的框架版本中,double的二进制表示会发生变化吗?
我发现的另一个替代方法是使用System.Decimal而不是double,并使用Decimal.GetBits()方法来提取它们。
有什么建议吗?

ct2axkht

ct2axkht1#

二进制格式不应该改变--这肯定是对现有规范的破坏性改变。正如Jimmy所说,它被定义为IEEE 754/ IEC 60559:1989格式(C#3.0语言规范1.3节;ECMA 335第8.2.2节)。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++;
    }

    …
}

这些注解在当时对我来说是有意义的,但我确信我现在必须考虑它们一段时间。在第一部分之后,你得到了“原始”指数和尾数--代码的其余部分只是帮助以一种更简单的方式处理它们。

puruo6ea

puruo6ea2#

该表示是IEEE标准,不应更改。
https://msdn.microsoft.com/en-us/library/system.double(v=vs.110).aspx
Double类型符合二进制浮点运算的IEC 60559:1989(IEEE 754)标准。
编辑:decimal有getBits而double没有的原因是decimal保留了有效数字。3.0000m == 3.00m但指数/尾数实际上是不同的。我认为float/double是唯一表示的。

相关问题