20 bit operations programmers should know
pixelstech.cn
pixelstech.cn
1.3, 2.2: wrong, shifting by negative number is undefined behavior
2.1: wrong, relies on some specific behavior for signed integer overflow
4, 5, 6, 7, 10, 11, 12, 17.1, 18: wrong, shifting negative numbers is implementation-defined behavior
Some examples will also suffer from integer overflow if the type 'int' is changed to something bigger (because then 1<<n could overflow, you'd need .e.g (uint64_t)1<<n).
Bitwise operations can be _extremely_ useful, but it's surprisingly difficult to use them in a correct and portable way. I have no idea where you can go to learn all the intricacies involved.
One killer that's always listed is "divide an int by 2: n >> 1" with no reference to how it behaves differently than the "/" operator (bitwise rounds towards negative infinity, / rounds towards zero). It's not incorrect, but that detail can be extremely important.
Although int has a 32 bit size on almost all systems it is only guaranteed to have a size of 16 bits.
The correct way of getting the size of int is including limits.h ( <climits> ) and looking at the value INT_MAX.
Entertaining book: http://www.amazon.co.uk/Hackers-Delight-2nd-Edition-ebook/dp...
The reference: http://www.amazon.co.uk/The-Computer-Programming-Vol-Combina... Section 7.1.3 Bitwise Tricks and Techniques
Besides, it's also wrong because left shifting a signed integer "into the sign bit" is undefined.
It annoys me that this kind of vacuous article is posted. It reminds me of an old rant about Perl tutorials: http://blogs.perl.org/users/mithaldu/2011/10/perl-tutorials-...
return 1 << n;
in which case it would also work for n == 0. The method shown in the article has a comment requiring n > 0.My latest use has been to store (multiple) categories of an item in a database in a single spot and do a quick search through bit operations (instead of joining to another table to fetch relations between item and categories).
int tmp = a; a = b; b = tmp;
It turned out that the bitwise swap was slower. In other words this sort of "clever" bit-level hack does not necessarily translate to higher performance.
And I would recommend the first chapter of "Matters Computational" written by Jörg Arndt, which includes many more advanced bitwise operations: http://www.jjj.de/fxt/#fxtbook. This book is more like a cookbook rather than an introductory book.
EDIT: debugged!
They also tend to have subtle differences in semantics compared to the "usual" way of doing things so beware.
Except if I wasn't using bit operations on a day to day basis, I wouldn't understand any of this "magic".
Okay sure, "programmers should know", yadda, yadda,... What about some of us who just don't know because they didn't go through C and don't know what is an integer?
Sue me, but until three years ago when I began being taught C, back when I only used ActionScript, JavaScript and PHP, I had no idea a number was "a suit of bits" and not just "a number". Same goes for linked-lists, binary trees,...
Not trying to "dumb down" HN, but let's not assume everyone knows everything.
But there's a special place in hell reserved for this:
> (a) ^= (b) ^= (a) ^= (b);
This is undefined because ^= is not a sequence point.
I feel like the title of this should be "how to demonstrate lack of C knowledge".