digitalmars.D.learn - bit twiddling (endianness)
- Lutger (22/22) Jan 08 2007 Hi, I need to convert a uint to 4 ubytes in big endian order for which I...
- Daniel Keep (6/29) Jan 08 2007 Taking, as an example, 0x0A0B0C0D: for little endian it should be stored...
- torhu (7/30) Jan 08 2007 Since you haven't done any weird casting, the compiler (or is it cpu?)
- Daniel Keep (4/39) Jan 08 2007 Yup: realised what it was he *actually* wanted about ten seconds ago.
- Lutger (5/38) Jan 08 2007 That explains a lot, especially why I wasn't able to figure it out! Now
- Stewart Gordon (7/16) Jan 10 2007 torhu is right - your code doesn't need to interrogate the platform byte...
- Lutger (2/7) Jan 11 2007 Cool, I've missed those somehow.
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; } }
Jan 08 2007
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
Jan 08 2007
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.
Jan 08 2007
torhu wrote:Lutger wrote:Yup: realised what it was he *actually* wanted about ten seconds ago. Ya beat me to it :P -- DanielHi, 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.
Jan 08 2007
torhu wrote:Lutger wrote: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.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.
Jan 08 2007
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.
Jan 10 2007
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.
Jan 11 2007