将float转换为二进制表示(使用MemoryStream?)

时间:2014-01-20 21:12:56

标签: c# binary memorystream floating-point-conversion

我想将给定的float转换为二进制表示形式。我试图将浮点值写入MemoryStream,逐字节读取此MemoryStream并将字节转换为二进制表示形式。但每次尝试都失败了。

  • “无法读取封闭的流”(但我只关闭了作者)
  • 出于测试目的,我只写了一个整数(我认为大小为4个字节),MemoryStream的长度为0,当我没有刷新StreamWriter时,1,当我那样。

我确信有更好的方法可以将float转换为二进制文件,但我还想了解一下MemoryStream类。

5 个答案:

答案 0 :(得分:9)

您可以使用BitConverter.GetBytes(float)或使用BinaryWriter包裹MemoryStream并使用BinaryWriter.Write(float)。目前尚不清楚您之前使用MemoryStream做了什么,但想要使用StreamWriter - 这是用于文本。

答案 1 :(得分:2)

使用BitConverter,而不是MemoryStream:

        // -7 produces "1 10000001 11000000000000000000000"
        static string FloatToBinary(float f)
        {
            StringBuilder sb = new StringBuilder();
            Byte[] ba = BitConverter.GetBytes(f);
            foreach (Byte b in ba)
                for (int i = 0; i < 8; i++)
                {
                    sb.Insert(0,((b>>i) & 1) == 1 ? "1" : "0");
                }
            string s = sb.ToString();
            string r = s.Substring(0, 1) + " " + s.Substring(1, 8) + " " + s.Substring(9); //sign exponent mantissa
            return r;
        }

答案 2 :(得分:1)

使用StreamWriter时可能会遇到陷阱,如下面的代码所示:

        // Write the float
        var f = 1.23456f;
        var ms = new MemoryStream();
        var writer = new StreamWriter(ms);
        writer.Write(f);
        writer.Flush();

        // Read 4 bytes to get the raw bytes (Ouch!)
        ms.Seek(0, SeekOrigin.Begin);
        var buffer = new char[4];
        var reader = new StreamReader(ms);
        reader.Read(buffer, 0, 4);
        for (int i = 0; i < 4; i++)
        {
            Console.Write("{0:X2}", (int)buffer[i]);
        }
        Console.WriteLine();

        // This is what you actually read: human readable text
        for (int i = 0; i < buffer.Length; i++)
        {
            Console.Write(buffer[i]);
        }
        Console.WriteLine();

        // This is what the float really looks like in memory.
        var bytes = BitConverter.GetBytes(f);
        for (int i = 0; i < bytes.Length; i++)
        {
            Console.Write("{0:X2}", (int)bytes[i]);
        }

        Console.ReadLine();

如果您希望流中只有4个字节并读取这4个字节,那么一切看起来都很好。但实际上长度为7并且您只读取了浮点文本表示的前4个字节。

将其与BitConverter的输出进行比较表明,使用StreamWriter在这里不正确。

答案 3 :(得分:1)

Dotnetfiddle

BitConverter.GetBytes(3.141f)
            .Reverse()
            .Select(x => Convert.ToString(x, 2))
            .Select(x => x.PadLeft(8, '0'))
            .Aggregate("0b", (a, b) => a + "_" + b);

// res = "0b_01000000_01001001_00000110_00100101"

无法抗拒使用“小型” LINQ查询。 也可以使用double。

答案 4 :(得分:0)

回答你的第一个问题:在.Net中,当你关闭/处理读写器时,基础流也会被关闭/处理。