我需要在C#中写一个big-endian单精度浮点数给文件

时间:2010-11-13 14:28:37

标签: c# floating-point endianness

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

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

    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方法会丢失文件格式所需的编码信息。

那么,如何在不丢失指数数据的情况下获取浮点数并更改其字节数?

2 个答案:

答案 0 :(得分:4)

你可以使用:

var bytes = BitConverter.GetBytes(floatVal);

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

还有一种方法可以使用不安全的代码,将float *视为一个字节*,这样你就可以按照你想要的顺序获取字节。

答案 1 :(得分:1)

我有点困惑为什么你的移位16位而不是8.Naw我理解为什么你需要RGB作为浮点数(它们通常每个1字节)。但是任何人。

你可以使用'假'联合将浮动视为一个uint

[StructLayout(LayoutKind.Explicit)]
public struct FloatIntUnion
{
    [FieldOffset(0)]        
    public  float f;
    [FieldOffset(0)]
    public uint i;
}

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

但我可能只会使用:

var bytes = BitConverter.GetBytes (RGB);
if (BitConverter.IsLittleEndian)
    Array.Reverse (bytes);
return bytes;

直到性能开始成为一个问题(因为这个方法(首先阅读配置文件))。