digitalmars.D.learn - little/big endian conversions
- lurker (3/3) Apr 08 2008 hi,
- Regan Heath (42/43) Apr 08 2008 This is a guess but if you read:
- Bill Baxter (4/61) Apr 08 2008 It doesn't matter that it's in IEEE 745 format. You just swap the bytes...
- Regan Heath (3/62) Apr 08 2008 Doh, for some reason I dismissed that as too simple.
- lurker (2/66) Apr 08 2008
- Bill Baxter (18/84) Apr 08 2008 You don't necessarily need to put it into a byte array. Just cast:
- lurker (2/91) Apr 09 2008
- Frank Benoit (11/16) Apr 09 2008 in tango there is the module tango.core.ByteSwap
hi, does anybody know how to convert float and doubles to little/big endian? thanks
Apr 08 2008
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
Regan Heath wrote:lurker wrote:It doesn't matter that it's in IEEE 745 format. You just swap the bytes like it was any old kind of data. --bbdoes 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 wrote:Regan Heath wrote:Doh, for some reason I dismissed that as too simple. Reganlurker wrote:It doesn't matter that it's in IEEE 745 format. You just swap the bytes like it was any old kind of data.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
so i need to put the float/double into an byte array and just swap? Regan Heath Wrote:Bill Baxter wrote:Regan Heath wrote:Doh, for some reason I dismissed that as too simple. Reganlurker wrote:It doesn't matter that it's in IEEE 745 format. You just swap the bytes like it was any old kind of data.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
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:Doh, for some reason I dismissed that as too simple. Reganlurker wrote:It doesn't matter that it's in IEEE 745 format. You just swap the bytes like it was any old kind of data.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
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:Doh, for some reason I dismissed that as too simple. Reganlurker wrote:It doesn't matter that it's in IEEE 745 format. You just swap the bytes like it was any old kind of data.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 09 2008
lurker schrieb:hi, does anybody know how to convert float and doubles to little/big endian? thanksin 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