tags:

views:

306

answers:

6

According to wiki shifts can be used to calculate powers of 2:

A left arithmetic shift by n is equivalent to multiplying by 2^n (provided the value does not overflow), while a right arithmetic shift by n of a two's complement value is equivalent to dividing by 2^n and rounding toward negative infinity.

I was always wondering if any other bitwise operators (~,|,&,^) make any mathematical sense when applied to base-10? I understand how they work, but do results of such operations can be used to calculate anything useful in decimal world?

+2  A: 

You can calculate logarithms using just bitwise operators...

http://tech.efreedom.com/Question/1-2255177/Finding-the-exponent-of-n-2-x-using-bitwise-operations-logarithm-in-base-2-of-n

eruciform
+3  A: 

Yes, there are other useful operations, but they tend to be oriented towards operations involving powers of 2 (for obvious reasons), e.g. test for odd/even, test for power of 2, round up/down to nearest power of 2, etc.

See Hacker's Delight by Henry S. Warren.

Paul R
+1 because Hacker's Delight is incredible.
Rich
+1  A: 

In every language I've used (admittedly, almost exclusively C and C-derivatives), the bitwise operators are exclusively integer operations (unless, of course, you override the operation).

While you can twiddle the bits of a decimal number (they have their own bits, after all), it's not necessarily going to get you the same result as twiddling the bits of an integer number. See Single Precision and Double Precision for descriptions of the bits in decimal numbers. See Fast Inverse Square Root for an example of advantageous usage of bit twiddling decimal numbers.

EDIT

For integral numbers, bitwise operations always make sense. The bitwise operations are designed for the integral numbers.

n << 1 == n * 2
n << 2 == n * 4
n << 3 == n * 8

n >> 1 == n / 2
n >> 2 == n / 4
n >> 3 == n / 8

n & 1 == {0, 1}       // Set containing 0 and 1
n & 2 == {0, 2}       // Set containing 0 and 2
n & 3 == {0, 1, 2, 3} // Set containing 0, 1, 2, and 3

n | 1 == {1, n, n+1}
n | 2 == {2, n, n+2}
n | 3 == {3, n, n+1, n+2, n+3}

And so on.

Brian S
I think you're confusing the term *decimal* with *floating point* - they are not the same thing - integers can be decimal for example.
Paul R
You raise an interesting point. There are actually much better reasons for tearing apart the bits of a `float` than of an `int`.
Heath Hunnicutt
@Paul R: I assumed serg was talking about non-integral numbers, because while you may enter an integer in decimal, hexadecimal, octal, or binary in many languages, the binary representation is identical, and they're still integers. (And if you output the value without any special consideration, most languages will use decimal regardless of what you wrote for input). `0b11001000 = 0310 = 200 = 0xC8`
Brian S
@Brian: yes, I guess the question is a little ambiguous. Normally though people would say "floating point" (or "fixed point" or whatever) if they are talking about numeric types other than integers.
Paul R
Sorry, I just meant base-10 numbers (ints, but if there are some interesting applications for floats that would be good too).
serg
Then yes, bitwise operations always make sense. Bitwise operations are designed for integral numbers, regardless of base. `n << 1 == n * 2` for an integral number `n`.
Brian S
Sorry, what does `{0, 1}` mean?
serg
Brian S
Ok, thanks. It would be nice if you could provide some comments for every expression explaining briefly what exactly is returned, it's hard to understand what those expressions mean.
serg
+1  A: 
phkahler
+5  A: 
BlueRaja - Danny Pflughoeft
starblue
+2  A: 

A fun trick to swap two integers without a temporary using bitwise XOR:

void swap(int &a, int &b) {
   a = a ^ b;
   b = b ^ a; //b now = a
   a = a ^ b; //knocks out the original a
}

This works because XOR is a commutative so a ^ b ^ b = a.

Rich