Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting 32 bit words out of 64-bit values in C/C++ and not worrying about endianness

It's my understanding that in C/C++ bitwise operators are supposed to be endian independent and behave the way you expect. I want to make sure that I'm truly getting the most significant and least significant words out of a 64-bit value and not worry about endianness of the machine. Here's an example:

uint64_t temp;
uint32_t msw, lsw;
msw = (temp & 0xFFFFFFFF00000000) >> 32;
lsw = temp & 0x00000000FFFFFFFF;

Will this work?

like image 822
Jay Atkinson Avatar asked Feb 03 '10 18:02

Jay Atkinson


People also ask

Does Endianness affect Bitwise operations?

Endianness only matters for layout of data in memory. As soon as data is loaded by the processor to be operated on, endianness is completely irrelevent. Shifts, bitwise operations, and so on perform as you would expect (data logically laid out as low-order bit to high) regardless of endianness.

Is C 32 or 64-bit?

Mostly compiler(gcc or clang) of C and C++, nowadays come with default 64-bit version.

Does C++ support 32 bit?

Microsoft C/C++ features support for sized integer types. You can declare 8-, 16-, 32-, or 64-bit integer variables by using the __intN type specifier, where N is 8, 16, 32, or 64.


2 Answers

6.5.7 Bitwise shift operators

4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

So, yes -- guranteed by the standard.

like image 112
dirkgently Avatar answered Oct 12 '22 07:10

dirkgently


It will work, but the strange propensity of some authors for doing bit-masking before bit-shifting always puzzled me.

In my opinion, a much more elegant approach would be the one that does the shift first

msw = (temp >> 32) & 0xFFFFFFFF; 
lsw = temp & 0xFFFFFFFF; 

at least because it uses the same "magic" bit-mask constant every time.

Now, if your target type is unsigned and already has the desired bit-width, masking becomes completely unnecesary

msw = temp >> 32; 
lsw = temp; 
like image 45
AnT Avatar answered Oct 12 '22 07:10

AnT