我通过手动转换和移动值将各种类型写入字节流。我发现这比使用BitConverter或BinaryWriter快三倍。
我的问题是花车。我需要将它们转换为int以便对它们执行移位操作,但是任何转换为int都将导致带截断的隐式转换等。我希望保持精确的二进制表示相同。这可能吗?
例如。我希望能够做到:
byte[] bytes = new byte[4];
float myFloat = 32.2;
//following won't compile as can't shift floats.
bytes [0] = (byte)myFloat;
bytes [1] = (byte)(myFloat >> 8);
bytes [2] = (byte)(myFloat >> 16);
bytes [3] = (byte)(myFloat >> 24);
答案 0 :(得分:15)
以下内容不需要不安全的代码,并且证明可以正常工作(我在各种.NET版本中使用了多年):
[StructLayout(LayoutKind.Explicit)]
public struct FloatAndUIntUnion
{
[FieldOffset(0)]
public uint UInt32Bits;
[FieldOffset(0)]
public float FloatValue;
}
FloatAndUIntUnion f2i = default(FloatAndUIntUnion);
f2i.FloatValue = aFloat; // write as float
uint i = f2i.UInt32Bits; // read back as int
请注意,float→int方向可以更简单:
int i = aFloat.GetHashCode();
然而,由于没有记录,它更加模糊 (根据MSDN),虽然由this post确认。 (也就是说,2006年的行为与2013年相同, 我认为将来没有理由改变它 - 但可能会发生, 而且我不确定它是否符合后向不兼容的条件 改变与否。)
答案 1 :(得分:6)
您可以使用double
代替float
吗?
double doubleValue = 32.2;
long setofBits = BitConverter.DoubleToInt64Bits(doubleValue);
编辑:回复评论
我相信使用BitConverter没有任何开销,使用Reflector我们可以看到它的实现非常简单:
public static unsafe long DoubleToInt64Bits(double value)
{
return *(((long*) &value));
}
答案 2 :(得分:5)
float myFloat = 0.124112f;
float[] floats = new[] { myFloat };
byte[] bytes = new byte[4];
Buffer.BlockCopy(floats, 0, bytes, 0, 4);
编辑:与DoubleToInt64Bits
相比,它在我的机器上慢了4倍,这与DoubleToInt64Bits
的极端简单性相比,因其阵列性质和不可避免的开销而有意义实施