Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
January 08, 2007 bit twiddling (endianness) | ||||
---|---|---|---|---|
| ||||
Hi, I need to convert a uint to 4 ubytes in big endian order for which I have written the function below. The thing is, I'm not 100% sure it is correct for Big Endian systems, would somebody be so kind as to inform me if this will work? void concatUint(inout ubyte[] bytestream, uint num) { bytestream.length = bytestream.length + 4; static if (std.system.endian == Endian.LittleEndian) { bytestream[$-4] = num >> 24; bytestream[$-3] = num >> 16; bytestream[$-2] = num >> 8; bytestream[$-1] = num; } else // big endian { bytestream[$-4] = num; bytestream[$-3] = num >> 8; bytestream[$-2] = num >> 16; bytestream[$-1] = num >> 24; } } |
January 08, 2007 Re: bit twiddling (endianness) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lutger | Lutger wrote: > Hi, I need to convert a uint to 4 ubytes in big endian order for which I have written the function below. The thing is, I'm not 100% sure it is correct for Big Endian systems, would somebody be so kind as to inform me if this will work? > > void concatUint(inout ubyte[] bytestream, uint num) > { > bytestream.length = bytestream.length + 4; > static if (std.system.endian == Endian.LittleEndian) > { > bytestream[$-4] = num >> 24; > bytestream[$-3] = num >> 16; > bytestream[$-2] = num >> 8; > bytestream[$-1] = num; > } > else // big endian > { > bytestream[$-4] = num; > bytestream[$-3] = num >> 8; > bytestream[$-2] = num >> 16; > bytestream[$-1] = num >> 24; > } > } Taking, as an example, 0x0A0B0C0D: for little endian it should be stored as 0x0D0C0B0A, and for big endian it should be 0x0A0B0C0D. 0x0A0B0C0D >> 24 == 0x0A, so I *think* you've got them backwards. http://en.wikipedia.org/wiki/Little_Endian#Big-endian -- Daniel |
January 08, 2007 Re: bit twiddling (endianness) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lutger | Lutger wrote:
> Hi, I need to convert a uint to 4 ubytes in big endian order for which I have written the function below. The thing is, I'm not 100% sure it is correct for Big Endian systems, would somebody be so kind as to inform me if this will work?
>
> void concatUint(inout ubyte[] bytestream, uint num)
> {
> bytestream.length = bytestream.length + 4;
> static if (std.system.endian == Endian.LittleEndian)
> {
> bytestream[$-4] = num >> 24;
> bytestream[$-3] = num >> 16;
> bytestream[$-2] = num >> 8;
> bytestream[$-1] = num;
> }
> else // big endian
> {
> bytestream[$-4] = num;
> bytestream[$-3] = num >> 8;
> bytestream[$-2] = num >> 16;
> bytestream[$-1] = num >> 24;
> }
> }
Since you haven't done any weird casting, the compiler (or is it cpu?) knows that num is an uint. So the bit shifting will behave like num is big endian, no matter the endianness of the system.
In other words, your code for little endian systems is correct for big endian too. But your big endian code swaps the byte order, resulting in little endian order in bytestream.
|
January 08, 2007 Re: bit twiddling (endianness) | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | torhu wrote:
> Lutger wrote:
>
>> Hi, I need to convert a uint to 4 ubytes in big endian order for which I have written the function below. The thing is, I'm not 100% sure it is correct for Big Endian systems, would somebody be so kind as to inform me if this will work?
>>
>> void concatUint(inout ubyte[] bytestream, uint num)
>> {
>> bytestream.length = bytestream.length + 4;
>> static if (std.system.endian == Endian.LittleEndian)
>> {
>> bytestream[$-4] = num >> 24;
>> bytestream[$-3] = num >> 16;
>> bytestream[$-2] = num >> 8;
>> bytestream[$-1] = num;
>> }
>> else // big endian
>> {
>> bytestream[$-4] = num;
>> bytestream[$-3] = num >> 8;
>> bytestream[$-2] = num >> 16;
>> bytestream[$-1] = num >> 24;
>> }
>> }
>
>
>
> Since you haven't done any weird casting, the compiler (or is it cpu?) knows that num is an uint. So the bit shifting will behave like num is big endian, no matter the endianness of the system.
>
> In other words, your code for little endian systems is correct for big endian too. But your big endian code swaps the byte order, resulting in little endian order in bytestream.
Yup: realised what it was he *actually* wanted about ten seconds ago. Ya beat me to it :P
-- Daniel
|
January 08, 2007 Re: bit twiddling (endianness) | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | torhu wrote:
> Lutger wrote:
>> Hi, I need to convert a uint to 4 ubytes in big endian order for which I have written the function below. The thing is, I'm not 100% sure it is correct for Big Endian systems, would somebody be so kind as to inform me if this will work?
>>
>> void concatUint(inout ubyte[] bytestream, uint num)
>> {
>> bytestream.length = bytestream.length + 4;
>> static if (std.system.endian == Endian.LittleEndian)
>> {
>> bytestream[$-4] = num >> 24;
>> bytestream[$-3] = num >> 16;
>> bytestream[$-2] = num >> 8;
>> bytestream[$-1] = num;
>> }
>> else // big endian
>> {
>> bytestream[$-4] = num;
>> bytestream[$-3] = num >> 8;
>> bytestream[$-2] = num >> 16;
>> bytestream[$-1] = num >> 24;
>> }
>> }
>
>
> Since you haven't done any weird casting, the compiler (or is it cpu?) knows that num is an uint. So the bit shifting will behave like num is big endian, no matter the endianness of the system.
>
> In other words, your code for little endian systems is correct for big endian too. But your big endian code swaps the byte order, resulting in little endian order in bytestream.
That explains a lot, especially why I wasn't able to figure it out! Now I wonder how I have got this weird assumption in my head that it would work different for big / little endian systems.
Thank you very much for clearing this up.
|
January 11, 2007 Re: bit twiddling (endianness) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lutger | Lutger wrote:
> Hi, I need to convert a uint to 4 ubytes in big endian order for which I have written the function below. The thing is, I'm not 100% sure it is correct for Big Endian systems, would somebody be so kind as to inform me if this will work?
>
> void concatUint(inout ubyte[] bytestream, uint num)
> {
> bytestream.length = bytestream.length + 4;
> static if (std.system.endian == Endian.LittleEndian)
torhu is right - your code doesn't need to interrogate the platform byte order.
But for future reference, if you ever do want to write endian-dependent code, you might version (LittleEndian) and version (BigEndian) nicer than examining std.system.endian.
Stewart.
|
January 11, 2007 Re: bit twiddling (endianness) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stewart Gordon | Stewart Gordon wrote:
> But for future reference, if you ever do want to write endian-dependent code, you might version (LittleEndian) and version (BigEndian) nicer than examining std.system.endian.
>
> Stewart.
Cool, I've missed those somehow.
|
Copyright © 1999-2021 by the D Language Foundation