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

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:
```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
```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