IEEE754 to floating point C#

僤鯓⒐⒋嵵緔 提交于 2019-12-11 19:34:21

问题


The below code is simple converting a 32bit-integer from the object being passed to the function, the 32-bit integer represents a floating number. I have checked with an online calculator that that i am getting the sign, exponent and mantessa the correct way but strangely i am getting the answer wrong.

Can anyone please check if i am mathematically (or maybe programmatically) doing it wrong somehow!?

Regards

public double FromFloatSafe(object f)
    {
        uint fb = Convert.ToUInt32(f);


        uint sign, exponent = 0, mantessa = 0;
        uint bias = 127;

        sign = (fb >> 31) & 1;
        exponent = (fb >> 23) & 0xFF;
        mantessa = (fb & 0x7FFFFF);
        double fSign = Math.Pow((-1), sign);
        double fMantessa = 1 + (1 / mantessa);
        double fExponent = Math.Pow(2, (exponent -bias));
        double ret = fSign * fMantessa * fExponent;
        return ret;
    }

回答1:


Something like that:

  uint fb = Convert.ToUInt32(f);

  return BitConverter.ToSingle(BitConverter.GetBytes((int) fb), 0);



回答2:


This handles even denormal numbers:

public static float FromFloatSafe(object f)
{
    uint fb = Convert.ToUInt32(f);

    int sign = (int)((fb >> 31) & 1);
    int exponent = (int)((fb >> 23) & 0xFF);
    int mantissa = (int)(fb & 0x7FFFFF);

    float fMantissa;
    float fSign = sign == 0 ? 1.0f : -1.0f;

    if (exponent != 0)
    {
        exponent -= 127;
        fMantissa = 1.0f + (mantissa / (float)0x800000);
    }
    else
    {
        if (mantissa != 0)
        {
            // denormal
            exponent -= 126;
            fMantissa = 1.0f / (float)0x800000;
        }
        else
        {
            // +0 and -0 cases
            fMantissa = 0;
        }
    }

    float fExponent = (float)Math.Pow(2.0, exponent);
    float ret = fSign * fMantissa * fExponent;
    return ret;
}

note that I do think there is something fishy here, but you asked for it, I wrote it... I feel this is a XY problem.

Ah... and note that while academically what I wrote is very interesting, I normally do it this way:

[StructLayout(LayoutKind.Explicit)]
public struct UInt32ToFloat
{
    [FieldOffset(0)]
    public uint UInt32;

    [FieldOffset(0)]
    public float Single;
}

then

float f = new UInt32ToFloat { UInt32 = Convert.ToUInt32(f) }.Single;


来源:https://stackoverflow.com/questions/31002050/ieee754-to-floating-point-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!