We were having endianness issues reading in some binary data in the
Windows version of my project at work… While we were able to use the
network byte-ordering routines (htons()
, etc) to swap the
integer values, byteswapping floats were a bit trickier… After beating my
head against the desk for a few hours yesterday, I gave up and went home…
When I got home I read the IEEE Floating Point spec (IEEE 754) until I
understood how they were represented in memory, and this morning I wrote
this code to properly do the swapping:
double fswap( float f ) { union { float f; unsigned char b[4]; } u1, u2; u1.f = f; u2.b[0] = u1.b[3]; u2.b[1] = u1.b[2]; u2.b[2] = u1.b[1]; u2.b[3] = u1.b[0]; return u2.f; }
When I first learned C a gojillion years ago I thought to myself “What
the hell could you possibly use a union
for?” Guess I found
the answer… :)
You’d have to change it up a bit to swap a double… Here’s a stab at an
implementation for doubles, although I haven’t tested it:
double dswap( double d ) { union { double d; unsigned char b[8]; } u1, u2; u1.d = d; u2.b[0] = u1.b[7]; u2.b[1] = u1.b[6]; u2.b[2] = u1.b[5]; u2.b[3] = u1.b[4]; u2.b[4] = u1.b[3]; u2.b[5] = u1.b[2]; u2.b[6] = u1.b[1]; u2.b[7] = u1.b[0]; return u2.d; }
Thought y’all might find it interesting, and it might be good to add to your
toolchest in case you ever run into this same problem.
Neat. That’s the first time I can remember seeing a union being useful.
I ended up having to use unions for the reiserfs endian safe code.
There is a struct that looks like this, and must remain in little endian order due to disk format restrictions. Simply setting the values won’t work unless the entire structure is treated as CPU order, which introduces complexity that becomes a pain to manage.
Unfortunately, this isn’t so easily handled because the split isn’t on a byte boundary.
The resulting code wasn’t particulary pretty, but gets the job done:
What is preventing you from just using htonl() & ntohl() and casting?
I just cut and pasted these from a google search..
I thought the same thing, and tried it first, but it didn’t work (on windows). I can’t look at the windows htonl source, so I’m not sure what they are doing that would cause it to not work.