8

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

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

我确信有一种更好的方法可以将floats 转换为二进制,但我也想了解一下这个MemoryStream类。

4

5 回答 5

15

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

于 2014-01-20T21:17:35.513 回答
5

使用 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;
        }
于 2017-05-27T03:25:02.123 回答
2

点网小提琴

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 查询。也适用于双倍。

于 2020-02-14T22:42:43.150 回答
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 是不正确的。

于 2014-01-20T21:33:44.850 回答
0

要回答您的第一个问题:在 .Net 中,当您关闭/处置读取器/写入器时,底层流也会被关闭/处置。

于 2017-01-06T11:59:15.807 回答