2011-01-20 22 views
6

Cách tốt nhất để chuyển đổi một số float thành byte[4] và sau đó quay lại 'phao' là gì?Chuyển 'phao' thành 'byte [4]' và quay lại 'phao' trong .NET Micro Framework

Tôi đang làm điều này trong C# .NET Micro Framework, vì vậy không có sẵn BitConverter để tôi sử dụng.

+1

cẩn thận endian (liên kết từ @Mitch cho thấy một lớp BitConverter sử dụng little endian) –

+1

Nền tảng đó mã hóa phao không có bất kỳ loại lớp BitConverter nào. Không có gì sử dụng lớp BitConverter của bất kỳ loại nào sẽ hoạt động. – chris12892

+0

Nevermind, có vẻ như đó là mã nguồn mở, tôi có thể trích xuất các bit ra mà tôi cần. – chris12892

Trả lời

2

Tôi đã sửa đổi lớp BitConverter từ a Netduino implementation để cho phép đặc điểm kỹ thuật cuối cùng (không phải là "cách tốt nhất", nhưng nó hoạt động). Nếu mảng byte được gửi qua mạng, tôi sẽ sử dụng BigEndian. Chỉ cần nhắc nhở rằng unsafe không được hỗ trợ chính thức trong NETMF.

using System; 
using System.Diagnostics; 

namespace netduino 
{ 
    public static class BitConverter 
    { 
     public static byte[] GetBytes(uint value) 
     { 
      return new byte[4] { 
        (byte)(value & 0xFF), 
        (byte)((value >> 8) & 0xFF), 
        (byte)((value >> 16) & 0xFF), 
        (byte)((value >> 24) & 0xFF) }; 
     } 

     public static unsafe byte[] GetBytes(float value) 
     { 
      uint val = *((uint*)&value); 
      return GetBytes(val); 
     } 

     public static unsafe byte[] GetBytes(float value, ByteOrder order) 
     { 
      byte[] bytes = GetBytes(value); 
      if (order != ByteOrder.LittleEndian) 
      { 
       System.Array.Reverse(bytes); 
      } 
      return bytes; 
     } 

     public static uint ToUInt32(byte[] value, int index) 
     { 
      return (uint)(
       value[0 + index] << 0 | 
       value[1 + index] << 8 | 
       value[2 + index] << 16 | 
       value[3 + index] << 24); 
     } 

     public static unsafe float ToSingle(byte[] value, int index) 
     { 
      uint i = ToUInt32(value, index); 
      return *(((float*)&i)); 
     } 

     public static unsafe float ToSingle(byte[] value, int index, ByteOrder order) 
     { 
      if (order != ByteOrder.LittleEndian) 
      { 
       System.Array.Reverse(value, index, value.Length); 
      } 
      return ToSingle(value, index); 
     } 

     public enum ByteOrder 
     { 
      LittleEndian, 
      BigEndian 
     } 

     static public bool IsLittleEndian 
     { 
      get 
      { 
       unsafe 
       { 
        int i = 1; 
        char* p = (char*)&i; 

        return (p[0] == 1); 
       } 
      } 
     } 
    } 
} 

namespace BitConverterTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      byte[] msbFirst = new byte[] { 0x42, 0xF6, 0xE9, 0xE0 }; 
      byte[] lsbFirst = new byte[] { 0xE0, 0xE9, 0xF6, 0x42 }; 
      const float f = 123.456789F; 

      byte[] b = netduino.BitConverter.GetBytes(f, netduino.BitConverter.ByteOrder.BigEndian); 
      for (int i = 0; i < b.Length; i++) 
      { 
       Debug.Assert(msbFirst[i] == b[i], "BitConverter.GetBytes(float, BigEndian) i=" + i); 
      } 

      Debug.Assert(f == netduino.BitConverter.ToSingle(msbFirst, 0, netduino.BitConverter.ByteOrder.BigEndian)); 

      Console.WriteLine("All tests passed"); 
      Console.ReadKey(); 
     } 
    } 
} 
9

Việc quy đổi từ uint để float (và ngược lại) có thể được thực hiện với mã "an toàn" là tốt (mặc dù tôi không biết nếu điều này là có thể trên NETMF hay không).

[StructLayout(LayoutKind.Explicit)] 
struct UIntFloat 
{  
    [FieldOffset(0)] 
    public float FloatValue; 

    [FieldOffset(0)] 
    public uint IntValue;   
} 

public static float ToSingle(byte[] value, int index)   
{   
    uint i = ToUInt32(value, index);    
    return ToSingle(i); 
} 

public static float ToSingle(uint value) 
{ 
    UIntFloat uf = new UIntFloat(); 
    uf.IntValue = value; 
    return uf.FloatValue; 
} 
1

này đã làm việc cho tôi, có thể không phải là câu trả lời đầy đủ nhất nhưng đơn giản

void floatToByte(GLubyte b[], float n) 
{ 
unsigned int val = *((unsigned int*)&n); 

b[0] = (GLubyte)(val & 0xFF); 
b[1] = (GLubyte)((val >> 8) & 0xFF); 
b[2] = (GLubyte)((val >> 16) & 0xFF); 
b[3] = (GLubyte)((val >> 24) & 0xFF); 
} 



float byteToFloat(GLubyte b[]) 
{ 
unsigned int ret = (unsigned int)(b[0] << 0 | b[1] << 8 | b[2] << 16 | b[3] << 24); 
float r = *(((float*)&ret)); 
return r; 
} 
Các vấn đề liên quan