Hacker's Delight

Category: Computer Science
Author: Henry S. Warren
All Stack Overflow 33
This Year Stack Overflow 2
This Month Stack Overflow 2


by anonymous   2019-07-21

Answering somewhat indirectly: a great reference on how bit twiddling routines like this (and hundreds of others) work is the book "Hacker's Delight" by Henry Warren. I highly recommend it -- it belongs on every programmer's bookshelf. http://www.amazon.com/Hackers-Delight-Henry-S-Warren/dp/0201914654

by anonymous   2019-07-21

Just round down to the nearest power of 2 and then XOR that with the original value, e.g. using flp2() from Hacker's Delight:

uint32_t flp2(uint32_t x) // round x down to nearest power of 2
    x = x | (x >> 1); 
    x = x | (x >> 2); 
    x = x | (x >> 4); 
    x = x | (x >> 8); 
    x = x | (x >>16); 
    return x - (x >> 1); 

uint32_t clr_msb(uint32_t x) // clear most significant set bit in x
    msb = flp2(x);  // get MS set bit in x
    return x ^ msb; // XOR MS set bit to clear it
by anonymous   2018-03-19

Using Guava, it's as simple as

long c = LongMath.checkedAdd(a, b); // throws an ArithmeticException on overflow

which is, I'd like to think, very readable indeed. (LongMath Javadoc here.)

For the sake of fairness, I'll mention that Apache Commons provides ArithmeticUtils.addAndCheck(long, long).

If you want to know how they work, well, the answer is one line of bit-hackery for Guava: the result doesn't overflow if (a ^ b) < 0 | (a ^ (a + b)) >= 0. This is based on the trick that the bitwise XOR of two numbers is nonnegative iff they have the same sign.

So (a ^ b) < 0 is true if a and b have different signs, and if that's the case it'll never overflow. Or, if (a ^ (a + b)) >= 0, then a + b has the same sign as a, so it didn't overflow and become negative.

(For more tricks like this, investigate the lovely book Hacker's Delight.)

Apache uses more complicated casework based on the sign of a and b.

by anonymous   2018-03-19

Here is a somewhat more efficient version of @hirschhornsalz's sum_and_overflow function:

void sum_and_overflow(__v4si a, __v4si b, __v4si& sum, __v4si& overflow)
   __v4si sa, sb;

    sum = _mm_add_epi32(a, b);                  // calculate sum
    sa = _mm_xor_si128(sum, a);                 // compare sign of sum with sign of a
    sb = _mm_xor_si128(sum, b);                 // compare sign of sum with sign of b
    overflow = _mm_and_si128(sa, sb);           // get overflow in sign bit
    overflow = _mm_srai_epi32(overflow, 31);    // convert to SIMD boolean (-1 == TRUE, 0 == FALSE)

It uses an expression for overflow detection from Hacker's Delight page 27:

sum = a + b;
overflow = (sum ^ a) & (sum ^ b);               // overflow flag in sign bit

Note that the overflow vector will contain the more conventional SIMD boolean values of -1 for TRUE (overflow) and 0 for FALSE (no overflow). If you only need the overflow in the sign bit and the other bits are "don't care" then you can omit the last line of the function, reducing the number of SIMD instructions from 5 to 4.

NB: this solution, as well as the previous solution on which it is based are for signed integer values. A solution for unsigned values will require a slightly different approach (see @Stephen Canon's answer).

by Piotr Lesnicki   2017-08-20

There is a book which gathers many of those 'magic tricks' and that may be interesting for you: The Hacker's Delight.

You have for example many tricks like bit twiddling hacks etc... (you have several square root algorithms for example that you can see on the google books version)

by anonymous   2017-08-20

I don't understand why all the answers to that question are the same.

There are several ways to calculate the square root from a number. One of them was proposed by Isaac Newton. I'll only write one of the simplest implementations of this method. I use it to improve the accuracy of double's square root.

// x - a number, from which we need to calculate the square root
// epsilon - an accuracy of calculation of the root from our number.
// The result of the calculations will differ from an actual value
// of the root on less than epslion.
public static decimal Sqrt(decimal x, decimal epsilon = 0.0M)
    if (x < 0) throw new OverflowException("Cannot calculate square root from a negative number");

    decimal current = (decimal)Math.Sqrt((double)x), previous;
        previous = current;
        if (previous == 0.0M) return 0;
        current = (previous + x / previous) / 2;
    while (Math.Abs(previous - current) > epsilon);
    return current;

About speed: in the worst case (epsilon = 0 and number is decimal.MaxValue) the loop repeats less than a three times.

If you want to know more, read this (Hacker's Delight by Henry S. Warren, Jr.)

by BlackJack   2017-08-19
I'm a rising junior at Yale, and I know Sean well and we both took systems programming together. We definitely covered bit manipulation and bit tricks, as well as number representation and lots of other stuff.

Sean's an incredibly bright guy but he's more interested in building world-changing apps and web dev. as opposed to low-level systems programming. There are other classes here where you have to code in assembly and do all sorts of bit manipulation (OS's comes to mind). The core CS sequence in our school is also in C, which differs notably from other places that use Python, Java, etc.

For anyone who wants to learn more about bit manipulation, Henry Warren's "Hacker's Delight" is a terrific book (http://www.amazon.com/Hackers-Delight-Henry-S-Warren/dp/0201...).

by azanar   2017-08-19
Another great resource for tidbits like this is _Hacker's Delight_, by Henry S. Warren, Jr. It covers a number of other tricks outside of bit twiddling, as well. Worth checking out for anyone who finds this sort of stuff fascinating.

Link: http://www.amazon.com/Hackers-Delight-Henry-S-Warren/dp/0201...

by axod   2017-08-19
Clever stuff. If you're interested in such things, best book I've seen is "Hackers Delight" http://www.amazon.com/Hackers-Delight-Henry-S-Warren/dp/0201...

Author covers really clever techniques to count bits, count non zero bytes like this etc etc. Bit manipulation at its best.