ubytes to ulong problem

Ali Çehreli acehreli at yahoo.com
Sat Dec 21 19:57:37 PST 2013


On 12/21/2013 05:44 PM, Charles Hixson wrote:
> On 12/21/2013 03:52 PM, Ali Çehreli wrote:
>> On 12/21/2013 03:13 PM, John Colvin wrote:
>>
>> > Ideally the compiler will optimise your version to be fast, but you may
>> > find you get better performance by doing the bit manipulations
>> eplicitly:
>>
>> Assuming that the program needs to support only big endian and little
>> endian systems (i.e. excluding systems where no D compiler exists :)),
>> the following is less wordy and should be equally fast:
>>
>> import std.bitmanip;
>> import std.system;
>>
>> ulong ubytesToUlong(ubyte[] block, size_t n = 0)
>> in
>> {
>>     assert (n >= 0);
>>     assert (n + 8 <= block.length);
>> }
>> body
>> {
>>     ulong value = *cast(ulong*)(block.ptr + n);
>>
>>     if (std.system.endian == Endian.littleEndian) {
>>         return *cast(ulong*)(value.nativeToBigEndian.ptr);
>>
>>     } else {
>>         return value;
>>     }
>> }
>>
>> Ali
>>
>>
> Will that work even when the alignment is to odd bytes?  Because that's
> the case I was really worried about.  The ubyte array is a packed
> mixture of types, some of which are isolated bytes.
>

No, it is not guaranteed to work unless the alignment is right.

How about this, then: :)

import std.array;

ulong ubytesToUlong(ubyte[] block, size_t n = 0)
in
{
     assert (n >= 0);
     assert (n + 8 <= block.length);
}
body
{
     ulong value = block.front;
     block.popFront();

     foreach (ub; block) {
         value <<= 8;
         value |= ub;
     }

     return value;
}

Ali



More information about the Digitalmars-d-learn mailing list