如何将 float
转换为 byte[4]
,然后再转回 'float' 呢?
我在使用 C# .NET 微框架 进行操作,所以无法使用 BitConverter
。
如何将 float
转换为 byte[4]
,然后再转回 'float' 呢?
我在使用 C# .NET 微框架 进行操作,所以无法使用 BitConverter
。
将 uint
转换为 float
(反之亦然)也可以使用“安全”的代码进行转换(但我不知道在NETMF上是否可能实现)。
[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;
}
我修改了Netduino实现中的BitConverter
类,使得可以指定字节序(这不是“最好的方法”,但它能正常工作)。如果要将字节数组发送到网络上,我会使用BigEndian
。需要提醒的是,在.NET Micro Framework中,unsafe
并没有官方支持。
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();
}
}
}
这对我有用,可能不是最完整的答案,但很简单
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;
}