ubyte[8] bytes = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]; ulong ii = cast(ulong)bytes[0] << 56 | cast(ulong)bytes[1] << 48 | cast(ulong)bytes[2] << 40 | cast(ulong)bytes[3] << 32; ulong i = ii | bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7]; assert(ii == 0x1234567800000000); // this is correct assert(i == 0x123456789abcdef0); // but this results in 0xFFFFFFFF9abcdef0 Weird!
Well, yes, bytes[4] << 24 == 0xffffffff9a000000, try it.
`bytes[4] << 24` gets promoted to int, and sign extended when or'd with a ulong. The same happens in C, and D committed to having the same integer promotion rules as C, so I don't see much that can be done here. Do you have a suggestion?
Oh wow; my bad. That's so obvious in retrospect, and terrible.