top | item 40479340

(no title)

xjay | 1 year ago

See also: Bit Twiddling Hacks

https://graphics.stanford.edu/~seander/bithacks.html

discuss

order

mike_hock|1 year ago

> Compute the sign of an integer

> On the other hand, if you prefer the result be either -1, 0, or +1, then use:

> sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));

> // Or, for more speed but less portability:

> sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1)); // -1, 0, or +1

> // Or, for portability, brevity, and (perhaps) speed:

> sign = (v > 0) - (v < 0); // -1, 0, or +1

Or if you prefer portability, speed, and readability at the same time:

    int sign(int i) {
        if(i > 0)
            return 1;
        else if(i < 0)
            return -1;
        else
            return 0;
    }
gets compiled to

        mov     ecx, edi
        sar     ecx, 31
        test    edi, edi
        mov     eax, 1
        cmovle  eax, ecx
        ret
which is the bit shift hack.

(still useful as a reference for implementing an optimizer, to be read as pseudo code)

jimbobthrowawy|1 year ago

I think a bunch of compilers nowadays are smart enough to see these kinds of hacks and compile them to an equivalent on the target that runs best. Favourite example of this is writing a duff's device to unroll a loop, and then gcc completely ignores it and replaces it with a vectorised loop.

richrichie|1 year ago

I was looking for this link. You made my morning!