1

I am converting a floating point value to binary string representation:

float resulta = 31.0 / 15.0;    //2.0666666
var rawbitsa = ToBinaryString(resulta); //returns 01000000000001000100010001000100

where ToBinaryString is coded as:

static string ToBinaryString(float value)
{

        int bitCount = sizeof(float) * 8; // never rely on your knowledge of the size
        // better not use string, to avoid ineffective string concatenation repeated in a loop
        char[] result = new char[bitCount]; 

        // now, most important thing: (int)value would be "semantic" cast of the same
        // mathematical value (with possible rounding), something we don't want; so:
        int intValue = System.BitConverter.ToInt32(BitConverter.GetBytes(value), 0);

        for (int bit = 0; bit < bitCount; ++bit)
        {
            int maskedValue = intValue & (1 << bit); // this is how shift and mask is done.
            if (maskedValue > 0)
                maskedValue = 1;
            // at this point, masked value is either int 0 or 1
            result[bitCount - bit - 1] = maskedValue.ToString()[0];
        }

        return new string(result); // string from character array
}

Now I want to convert this binary string to float value.

I tried the following but it returns value "2.8293250329111622E-315"

string bstra = "01000000000001000100010001000100";
long w = 0;
for (int i = bstra.Length - 1; i >= 0; i--) w = (w << 1) + (bstra[i] - '0');
double da = BitConverter.ToDouble(BitConverter.GetBytes(w), 0); //returns 2.8293250329111622E-315

I want the value "2.0666666" by passing in value "01000000000001000100010001000100"

Why am I getting a wrong value? Am I missing something?

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
usrso
  • 65
  • 2
  • 7
  • 2
    Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – SᴇM Jan 12 '20 at 14:30
  • 1
    You can have a look at this [thread](https://stackoverflow.com/questions/21244252/convert-float-to-its-binary-representation-using-memorystream) – Pavel Anikhouski Jan 12 '20 at 14:39
  • 1
    @SᴇM This isn't math. This is effectively serializing and de-serializing the value. – juharr Jan 12 '20 at 14:44
  • 1
    There's a lot of confusion in the reversal code where it is using long/double instead of int/float - this **really matters**, but: the actual bit processing code doesn't work; you should be able to regenerate `w` as the same value as whatever `intValue` was originally. Until *that* works, nothing else will. Check whether you're reading the bits backwards, perhaps. – Marc Gravell Jan 12 '20 at 15:09
  • 1
    Please provide links if you are taking someone else's code and using that in your example, https://www.codeproject.com/Questions/484209/Convertplusfloatplustoplusbinary – Jawad Jan 12 '20 at 15:14

1 Answers1

4

You're making this a lot harder than it needs to be; the error seems to be mostly in the character parsing code, but you don't need to do all that.

You could try like this instead:

static string ToBinaryString(float value)
{
    const int bitCount = sizeof(float) * 8;
    int intValue = System.BitConverter.ToInt32(BitConverter.GetBytes(value), 0);
    return Convert.ToString(intValue, 2).PadLeft(bitCount, '0');
}

static float FromBinaryString(string bstra)
{
    int intValue = Convert.ToInt32(bstra, 2);
    return BitConverter.ToSingle(BitConverter.GetBytes(intValue), 0);
}

Example:

float resulta = 31.0F / 15.0F; //2.0666666
var rawbitsa = ToBinaryString(resulta);
Console.WriteLine(rawbitsa); //01000000000001000100010001000100
var back = FromBinaryString(rawbitsa);
Console.WriteLine(back); //2.0666666

Note that the usage of GetBytes is kinda inefficient; if you're OK with unsafe code, you can remove all of that.

Also note that this code is CPU-specific - it depends on the endianness.

CodingYoshi
  • 25,467
  • 4
  • 62
  • 64
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • "but you **don't** need to write this"? I find it confusing. – CodingYoshi Jan 12 '20 at 15:55
  • @CodingYoshi the OP is writing a lot of code to convert an integer to the binary string of that value, and vice versa. There are inbuilt utility methods to do this, which makes the code a: simpler, and b: correct – Marc Gravell Jan 12 '20 at 16:13
  • Thanks Marc. How do we go about double values? i.e. static string ToBinaryString(double value) and static double FromBinaryString(string bstra) – usrso Jan 13 '20 at 05:16
  • it should be largely identical, but `int` becomes `long`, `Int32` becomes `Int64`, `Single` becomes `Double`, `float` becomes `double` – Marc Gravell Jan 13 '20 at 11:18