开发者

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

I have a file format I'm trying to write to using C#. The format encodes integer-based RGB color values as a floating point. It also stores the values as big-endian. I found an example of what I'm trying to do, written in php, here: http://www.colourlovers.com/ase.phps

I can convert the endian-ness easily. I know this code is very verbose, but I'm just using it to watch the bits swap during troubleshooting.

    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# won't let me perform bit-shifts on floats. Converting to an int or uint to call my SwapEndian method above loses the encoding i开发者_如何转开发nformation the file format requires.

So, how would you take a floating point number and change its endian-ness without losing the exponent data?


You could just use:

var bytes = BitConverter.GetBytes(floatVal);

And reverse the array (assuming the CPU is little-endian, which you an check), or simply just access the array in the order you need.

There is also a way to do this with unsafe code, treating the float* as a byte* so you can get the bytes in the order you want.


I'm slightly confused as to why your shifting by 16 bits rather than 8. Naw do I understand why you need RGB as a float (they are generaly 1 byte each). But anywho.

you can use a 'fake' union to treat a float as an uint

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

this allows you to assign the float and then provide do bitwise operations on the uint part of the 'union' then use the float again as the final value.

However I would probably just use:

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

until performance started to become an issue (because of THIS method (read profile first)).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜