我需要在C#中将大端单精度浮点数写入文件

I need to write a big-endian single-precision floating point number to file in C#

我尝试使用C#编写一种文件格式。该格式将基于整数的RGB颜色值编码为浮点。它还将值存储为big-endian。我在这里找到了用php编写的我想做的事的示例:http://www.colourlovers.com/ase.phps

我可以轻松转换字节序。我知道这段代码很冗长,但是我只是用它来观察故障排除过程中的位交换。

1
2
3
4
5
6
7
8
9
10
11
12
    private uint SwapEndian(uint host) {
        uint ReturnValue;
        uint FirstHalf;
        uint LastHalf;
        FirstHalf = (host & 0xFFFF0000);
        FirstHalf = (FirstHalf >> 16);
        LastHalf = (host & 0x0000FFFF);
        LastHalf = (LastHalf << 16);
        ReturnValue = (FirstHalf | LastHalf);
        return ReturnValue;

    }

C#不允许我对浮点数执行位移位。转换为int或uint以调用上面的SwapEndian方法将丢失文件格式所需的编码信息。

那么,您如何获取一个浮点数并更改其字节序而??不丢失指数数据?


您可以使用:

1
var bytes = BitConverter.GetBytes(floatVal);

并反转数组(假设CPU是little-endian,您可以检查一下),或者只是按照所需的顺序访问数组。

还有一种使用不安全代码执行此操作的方法,将float *视为字节*,这样您就可以按想要的顺序获取字节。


对于为什么要移位16位而不是8位,我有些困惑。我不明白为什么您需要RGB作为浮点数(它们通常每个为1字节)。但是任何人。

您可以使用\\'fake \\'联合将浮点数视为uint

1
2
3
4
5
6
7
8
[StructLayout(LayoutKind.Explicit)]
public struct FloatIntUnion
{
    [FieldOffset(0)]        
    public  float f;
    [FieldOffset(0)]
    public uint i;
}

这允许您分配float,然后对" union"的uint部分提供按位操作,然后再次使用float作为最终值。

但是我可能只会使用:

1
2
3
4
var bytes = BitConverter.GetBytes (RGB);
if (BitConverter.IsLittleEndian)
    Array.Reverse (bytes);
return bytes;

直到性能开始成为一个问题(由于使用THIS方法(首先读取配置文件))。