2014-01-20 3 views
5

Я хотел бы преобразовать заданный float в его двоичное представление. Я попытался записать значение float в MemoryStream, прочесть это MemoryStream байт байтом и преобразовать байты в их двоичное представление. Но каждая попытка не удалась.Преобразование float в его двоичное представление (используя MemoryStream?)

  • «Невозможно прочитать замкнутый поток» (но я только закрыл писатель)
  • Для целей тестирования я просто написал целое число (я думаю, что четыре байта) и длина MemoryStream была 0, когда я не сбросил StreamWriter и 1, когда я это сделал.

Я уверен, что есть лучший способ преобразовать float S в двоичный, но я также хотел бы узнать немного о MemoryStream классе.

ответ

8

Вы можете использовать BitConverter.GetBytes(float) или использовать упаковку BinaryWriter и использовать BinaryWriter.Write(float). Не совсем точно, что вы делали с MemoryStream раньше, но вы не хотите использовать StreamWriter - это для текста.

+0

OK. Я всегда забываю, какой класс использовать для конкретной цели :) Спасибо за быстрый ответ :) – Cubinator73

+1

@ Cubinator73: Для этого нужна документация. Например, из 'StreamWriter':« Реализует TextWriter для записи символов в поток в определенной кодировке »- это не то, что вам нужно. –

+0

Существует ли более эффективный подход, который, например, записывает данные в 'uint' (для' float') и 'ulong' (для' double')? Использование массива 'byte []', вероятно, требует построения объекта в куче и не обеспечивает простой побитовой манипуляции. –

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 байта текстового представления float.

Сравнивая это с выходом BitConverter, показано, что использование StreamWriter здесь неверно.

+0

Являются ли последние три байта спецификацией? – Cubinator73

+0

Нет, последние 3 байта составляют 456 номера 1.23456. Первые 4 байта составляют 1,23 (включая точку) номера 1.23456. –

0

Чтобы ответить на ваш первый вопрос: в .Net, когда вы закрываете/удаляете считыватель/запись, базовый поток также закрывается/удаляется.

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; 
     } 
Смежные вопросы