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?
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
prev sibling next sibling parent lurker <lurker lurker.com> writes:
thank you all for your help!!

Bill Baxter Wrote:

 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?
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 09 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