www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - little/big endian conversions

reply lurker <lurker lurker.com> writes:
hi,

does anybody know how to convert float and doubles to little/big endian?

thanks
Apr 08 2008
next sibling parent reply Regan Heath <regan netmail.co.nz> writes:
lurker wrote:
 does anybody know how to convert float and doubles to little/big endian?

This is a guess but if you read: http://en.wikipedia.org/wiki/IEEE_754 You'll see the internal representation of a float, given that and a little guess work I've come up with: import std.stdio; int extractSign(float f) { return (*(cast(int*)&f) & 0x80000000) ? -1 : 1; } ubyte extractExp(float f) { return (*(cast(int*)&f) << 1) & 0xFF000000; } int extractFraction(float f) { return *(cast(int*)&f) & 0x007FFFFF; } void main() { float f = -1.25f; auto sign = extractSign(f); auto exp = extractExp(f); auto fraction = extractFraction(f); writefln(f); writefln(sign); writefln(exp); writefln(fraction); } which will extract the various parts of a float. Now, I have no idea how they might change on a big/little endian system but I suspect each part would have it's byte order swapped. In which case, byte order swapping the extracted parts then re-assembling might give you a byte order swapped float. Like I said, I'm guessing. What you want is 2 systems with different ordering and then you want to dump the content of the float like this: writefln("%032b", *(cast(int*)&f)); then compare. Regan
Apr 08 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Regan Heath wrote:
 lurker wrote:
 does anybody know how to convert float and doubles to little/big endian?

This is a guess but if you read: http://en.wikipedia.org/wiki/IEEE_754 You'll see the internal representation of a float, given that and a little guess work I've come up with: import std.stdio; int extractSign(float f) { return (*(cast(int*)&f) & 0x80000000) ? -1 : 1; } ubyte extractExp(float f) { return (*(cast(int*)&f) << 1) & 0xFF000000; } int extractFraction(float f) { return *(cast(int*)&f) & 0x007FFFFF; } void main() { float f = -1.25f; auto sign = extractSign(f); auto exp = extractExp(f); auto fraction = extractFraction(f); writefln(f); writefln(sign); writefln(exp); writefln(fraction); } which will extract the various parts of a float. Now, I have no idea how they might change on a big/little endian system but I suspect each part would have it's byte order swapped. In which case, byte order swapping the extracted parts then re-assembling might give you a byte order swapped float. Like I said, I'm guessing. What you want is 2 systems with different ordering and then you want to dump the content of the float like this: writefln("%032b", *(cast(int*)&f)); then compare. Regan

It doesn't matter that it's in IEEE 745 format. You just swap the bytes like it was any old kind of data. --bb
Apr 08 2008
parent reply Regan Heath <regan netmail.co.nz> writes:
Bill Baxter wrote:
 Regan Heath wrote:
 lurker wrote:
 does anybody know how to convert float and doubles to little/big endian?

This is a guess but if you read: http://en.wikipedia.org/wiki/IEEE_754 You'll see the internal representation of a float, given that and a little guess work I've come up with: import std.stdio; int extractSign(float f) { return (*(cast(int*)&f) & 0x80000000) ? -1 : 1; } ubyte extractExp(float f) { return (*(cast(int*)&f) << 1) & 0xFF000000; } int extractFraction(float f) { return *(cast(int*)&f) & 0x007FFFFF; } void main() { float f = -1.25f; auto sign = extractSign(f); auto exp = extractExp(f); auto fraction = extractFraction(f); writefln(f); writefln(sign); writefln(exp); writefln(fraction); } which will extract the various parts of a float. Now, I have no idea how they might change on a big/little endian system but I suspect each part would have it's byte order swapped. In which case, byte order swapping the extracted parts then re-assembling might give you a byte order swapped float. Like I said, I'm guessing. What you want is 2 systems with different ordering and then you want to dump the content of the float like this: writefln("%032b", *(cast(int*)&f)); then compare. Regan

It doesn't matter that it's in IEEE 745 format. You just swap the bytes like it was any old kind of data.

Doh, for some reason I dismissed that as too simple. Regan
Apr 08 2008
parent reply lurker <lurker lurker.com> writes:
so i need to put the float/double into an byte array and just swap?

Regan Heath Wrote:

 Bill Baxter wrote:
 Regan Heath wrote:
 lurker wrote:
 does anybody know how to convert float and doubles to little/big endian?

This is a guess but if you read: http://en.wikipedia.org/wiki/IEEE_754 You'll see the internal representation of a float, given that and a little guess work I've come up with: import std.stdio; int extractSign(float f) { return (*(cast(int*)&f) & 0x80000000) ? -1 : 1; } ubyte extractExp(float f) { return (*(cast(int*)&f) << 1) & 0xFF000000; } int extractFraction(float f) { return *(cast(int*)&f) & 0x007FFFFF; } void main() { float f = -1.25f; auto sign = extractSign(f); auto exp = extractExp(f); auto fraction = extractFraction(f); writefln(f); writefln(sign); writefln(exp); writefln(fraction); } which will extract the various parts of a float. Now, I have no idea how they might change on a big/little endian system but I suspect each part would have it's byte order swapped. In which case, byte order swapping the extracted parts then re-assembling might give you a byte order swapped float. Like I said, I'm guessing. What you want is 2 systems with different ordering and then you want to dump the content of the float like this: writefln("%032b", *(cast(int*)&f)); then compare. Regan

It doesn't matter that it's in IEEE 745 format. You just swap the bytes like it was any old kind of data.

Doh, for some reason I dismissed that as too simple. Regan

Apr 08 2008
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
You don't necessarily need to put it into a byte array.  Just cast:

   void swap(ref byte a, ref byte b) {
      byte tmp; tmp=a; a=b; b=tmp;
   }
   float f;
   byte[4] fbytes = (cast(byte*)&f)[0..4];
   swap(fbytes[0],fbytes[3]);
   swap(fbytes[1],fbytes[2]);
   float fswapped = *(cast(float*)fbytes.ptr);

Or instead of casts you can use a union.

     union FC { float f;      ubyte[4] c; }
     FC fs;
     fs.f = f;
     swap(fs.c[0],fs.c[3]);
     swap(fs.c[1],fs.c[2]);
     float fswapped = fs.f;

--bb

lurker wrote:
 so i need to put the float/double into an byte array and just swap?
 
 Regan Heath Wrote:
 
 Bill Baxter wrote:
 Regan Heath wrote:
 lurker wrote:
 does anybody know how to convert float and doubles to little/big endian?

http://en.wikipedia.org/wiki/IEEE_754 You'll see the internal representation of a float, given that and a little guess work I've come up with: import std.stdio; int extractSign(float f) { return (*(cast(int*)&f) & 0x80000000) ? -1 : 1; } ubyte extractExp(float f) { return (*(cast(int*)&f) << 1) & 0xFF000000; } int extractFraction(float f) { return *(cast(int*)&f) & 0x007FFFFF; } void main() { float f = -1.25f; auto sign = extractSign(f); auto exp = extractExp(f); auto fraction = extractFraction(f); writefln(f); writefln(sign); writefln(exp); writefln(fraction); } which will extract the various parts of a float. Now, I have no idea how they might change on a big/little endian system but I suspect each part would have it's byte order swapped. In which case, byte order swapping the extracted parts then re-assembling might give you a byte order swapped float. Like I said, I'm guessing. What you want is 2 systems with different ordering and then you want to dump the content of the float like this: writefln("%032b", *(cast(int*)&f)); then compare. Regan

It doesn't matter that it's in IEEE 745 format. You just swap the bytes like it was any old kind of data.

Regan


Apr 08 2008
prev sibling parent Frank Benoit <keinfarbton googlemail.com> writes:
lurker schrieb:
 hi,
 
 does anybody know how to convert float and doubles to little/big endian?
 
 thanks

in tango there is the module tango.core.ByteSwap The function static final void swap32 (void* dst, uint bytes); can be used for one float or a float array. float a; swap32( &a, 4 ); float[10] b; swap32( b.ptr, b.length*4 ); See http://dsource.org/projects/tango/docs/current/tango.core.ByteSwap.html
Apr 09 2008