Question

I have this macro

#define get32(buf) ((((*(buf))<<24)&0xff000000) + \
        (((*((buf)+1))<<16)&0x00ff0000) + \
        (((*((buf)+2))<< 8)&0x0000ff00) + \
        (((*((buf)+3)    )&0x000000ff)))

Which, to my understanding, assumes in buff, bytes are encoded in big endian way, and converts them to a 32 bit integer, right?

What confused me was that I was expecting | operator inside the macro instead of +?

Was it helpful?

Solution

It is conventional and sane to use | but + works when everything is unsigned and the numbers to be added have disjoint ranges of bits. If the ranges of bits overlapped, then addition and logical or are not equivalent.

Out of curiosity I was wondering how these functions are implemented when the integer is negative for example.

The way I'd probably implement the macro is:

#define get32(buf) ((((buf)[0] & 0xFF) << 24) | \
                    (((buf)[1] & 0xFF) << 16) | \
                    (((buf)[2] & 0xFF) <<  8) | \
                    (((buf)[3] & 0xFF) <<  0))

The main difference is that the lines are more systematic; the optimizer will eliminate the << 0 operation (probably even if the -O flag is not used). This will handle negative numbers OK in practice (numbers where the high bit of buf[0] is set).

OTHER TIPS

'+' is doing same thing as of | . for example: number is 345678. while doing with +:

 340000
+005600
+000078

while doing with | kindly use bits:

 340000 [as bits]
|005600 [as bits]
|000078 [as bits]

seems there is no difference.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top