www.digitalmars.com Home | Search | C & C++ | D | DMDScript | News Groups | index | prev | next
Archives

D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.ide
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger

C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows

digitalmars.empire
digitalmars.DMDScript
electronics



digitalmars.D.learn - little/big endian conversions

↑ ↓ ← lurker <lurker lurker.com> writes:
hi,

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

thanks
Apr 08 2008
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
↑ ↓ 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
↑ ↓ 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
↑ ↓ 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
↑ ↓ → 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
→ 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