将float强制转换为int而不进行ANY转换

本文关键字:转换 ANY float int | 更新日期: 2023-09-27 18:13:56

我正在通过手动强制转换和移位值向字节流写入各种类型。我发现这比使用BitConverter或BinaryWriter快三倍多。

我的问题是浮子。为了对它们执行移位操作,我需要将它们强制转换为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);

将float强制转换为int而不进行ANY转换

以下内容不需要不安全的代码,并且已被证明有效(我在各种.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(,尽管这篇文章证实了这一点。(也就是说,2006年的行为与2013年相同,我认为没有理由在未来改变它—但它可能会发生,我不确定它是否符合向后不兼容的条件是否更改。(

你能用double代替float吗?

double doubleValue = 32.2;
long setofBits = BitConverter.DoubleToInt64Bits(doubleValue);

编辑:回答评论

我相信使用BitConverter没有任何开销,使用Reflector我们可以看到它的实现非常简单:

public static unsafe long DoubleToInt64Bits(double value)
{
    return *(((long*) &value));
}
float myFloat = 0.124112f;
float[] floats = new[] { myFloat };
byte[] bytes = new byte[4];
Buffer.BlockCopy(floats, 0, bytes, 0, 4);

EDIT:DoubleToInt64Bits相比,它的速度较慢,尽管在我的机器上大约慢了4倍,考虑到它的阵列性质和与DoubleToInt64Bits实现的极端简单性相比不可避免的开销,这是有道理的。