Hacker News new | ask | show | jobs
by xjay 749 days ago
See also: Bit Twiddling Hacks

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

4 comments

Or the delightful Hacker's Delight by Henry S. Warren, Jr.

https://en.wikipedia.org/wiki/Hacker%27s_Delight

> 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)

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.
Similar but for general math and optimizations:

http://www.hakmem.org/

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