Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
April 08, 2008 little/big endian conversions | ||||
---|---|---|---|---|
| ||||
hi, does anybody know how to convert float and doubles to little/big endian? thanks |
April 08, 2008 Re: little/big endian conversions | ||||
---|---|---|---|---|
| ||||
Posted in reply to lurker | 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 Re: little/big endian conversions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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 Re: little/big endian conversions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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 Re: little/big endian conversions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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 Re: little/big endian conversions | ||||
---|---|---|---|---|
| ||||
Posted in reply to lurker | 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 Re: little/big endian conversions | ||||
---|---|---|---|---|
| ||||
Posted in reply to lurker | 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 |
Copyright © 1999-2021 by the D Language Foundation