Thread overview
little/big endian conversions
Apr 08, 2008
lurker
Apr 08, 2008
Regan Heath
Apr 08, 2008
Bill Baxter
Apr 08, 2008
Regan Heath
Apr 08, 2008
lurker
Apr 08, 2008
Bill Baxter
Apr 09, 2008
Frank Benoit
April 08, 2008
hi,

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

thanks
April 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
April 08, 2008
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
April 08, 2008
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
April 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:
> >> 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

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