Coincidence of bitwise and and bitwise or operators? - c

So, while playing with the bitwise AND and bitwise OR operators, I noticed the following:
(a & b) + (a | b) = a + b
and there is a corresponding proof which mainly relies on the fact for any two bits x and y,
(a,b) = (0,0) --> (a&b, a|b) = (0, 0) = (a, b)
(a,b) = (0,1) --> (a&b, a|b) = (0, 1) = (a, b)
(a,b) = (1,0) --> (a&b, a|b) = (0, 1) = (b, a)
(a,b) = (1,1) --> (a&b, a|b) = (1, 1) = (b, a)
Now, I was wondering - is this a mere coincidence, or are these bitwise operations actually used in this way? I don't think that computers actually compute addition in this way, since it would be a recursive definition... but it seems too nice of a property to have been random!

AND and OR are idempotent and commutative:
a & a = a
a | a = a
a & b = b & a
a | b = b | a
They also absorb each other:
a & (a | b) = a
a | (a & b) = a
Thus:
a + b = (a | a) + (b & b)
a + b = (a | (a & b)) + (b & (a | b))
(a | a) + (b & b) = (a | (a & b)) + (b & (a | b))
a + b = (a & b) + (a | b)
Another way to see it is that, for two bits x and y, x + y = x | y and x & y = 0 unless both bits are set, and then x & y adds the missing bit to x | y.

when a and b value only 0 or 1 it is not surprising to have (a & b) + (a | b) == a + b
having both a and b valuing 1 (a & b) and (a | b) value 1, so you do 1+1 on each side of ==
else (a & b) is obviously 0 so you compare a|b and a+b while there is no possible carry on a+b and in that case a and b being a boolean do use + or | is the same
Note when a and b value only 0 or 1 then a&b equals a*b in all cases

(a & b) + (a | b) = a + b is indeed true in general, not just for 0 and 1.
An other way to look at it, is that whenever the bits in a and b at a particular position are different (so one of them is zero and the other is one), then in (a & b) + (a | b) the 0 is put on the left hand side of the + and the 1 is put on the right hand side. If the bits are the same then it doesn't make any difference.
It's like a more granular form of min(a, b) + max(a, b), at the bit level intead of the word level.
Reordering bits like that has no effect on the sum. Consider that both a and b are already sums, of the form a[0] + 2*a[1] + 4*a[2] .... a + b is a bigger sum, and (a & b) + (a | b) merely reordered the terms of that sum.

Related

k&r exercise 2-6 "setbits"

I've seen the answer here: http://clc-wiki.net/wiki/K%26R2_solutions:Chapter_2:Exercise_6
and i've tested the first, but in this part:
x = 29638;
y = 999;
p = 10;
n = 8;
return (x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n)))))
in a paper it give to me a 6, but in the program it return 28678...
in this part:
111001111000110
&000100000000111
in the result, the left-most three bits has to be 1's like in x but the bitwise operator & says:
The output of bitwise AND is 1 if the corresponding bits of all operands is 1. If either bit of an operand is 0, the result of corresponding bit is evaluated to 0.
so why it returns the number with thats 3 bits in 1?
Here we go, one step at a time (using 16-bit numbers). We start with:
(x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n)))))
Substituting in numbers (in decimal):
(29638 & ((~0 << (10 + 1)) | (~(~0 << (10 + 1 - 8)))))
Totalling up the bit shift amounts gives:
(29638 & ((~0 << 11) | (~(~0 << 3))))
Rewriting numbers as binary and applying the ~0s...
(0111001111000110 & ((1111111111111111 << 1011) | (~(1111111111111111 << 0011))))
After performing the shifts we get:
(0111001111000110 & (1111100000000000 | (~ 1111111111111000)))
Applying the other bitwise-NOT (~):
(0111001111000110 & (1111100000000000 | 0000000000000111))
And the bitwise-OR (|):
0111001111000110 & 1111100000000111
And finally the bitwise-AND (&):
0111000000000110
So we then have binary 0111000000000110, which is 2 + 4 + 4096 + 8192 + 16384, which is 28678.

Using bitwise operators ~ and & to make | Operator

I've got to solve a task but can't find the answer:
Compute x | y using only ~ and &
The maximum allowed operations are 8
Edit:
In twos complement and 32-bit representations of integers.
Right shifts are performed arithmetically.
By looking at the truth table of x | y you will see:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
x | y will be 1 if bothx and y are not 0. You can translate it to ~(~x & ~y):
~(~0 & ~0) = ~(1 & 1) = ~1 = 0
~(~0 & ~1) = ~(1 & 0) = ~0 = 1
~(~1 & ~0) = ~(0 & 1) = ~0 = 1
~(~1 & ~1) = ~(0 & 0) = ~0 = 1
This has already been answered, but they made no reference to De Morgan.
De Morgan's Law says that ~(~A & ~B) is equivalent to (A | B). My professor in Logic Design told us to "move bubble, change symbol" where a NOT (~) is a "bubble" and AND/OR are "symbols".
(A' & B')' -> move/distribute the "bubbles" -> (A & B) -> change the "symbol" -> (A | B).
This also works backwards, where the lack of a NOT can be treated as no bubble at all.
(A | B) -> add "bubbles" -> (A' | B')' -> change the symbol -> (A' & B')'
See De Morgan's Laws for some more information.

Differentiating sums with Maxima

I have the following sum:
sum((R[i]-(a*X[i]+b)*t + 1/2*(c*X[i]+d)^2*t)^2/((c*X[i]+d)^2*t), i, 1, N);
which I want to differenciate wrt. a:
diff(%, a);
but Maxima (wxMaxima to be precise) just prints d/da . Can I
make it actually differentiate the sum (so because N is finite is
should differentiate every element in the sum separately)?
If I set N to some constant, e.g.:
sum((R[i]-(a*X[i]+b)*t + 1/2*(c*X[i]+d)^2*t)^2/((c*X[i]+d)^2*t), i, 1, 100);
then I get explicit sum of 100 elements (takes about 2 pages), and
then differentiation works (but again I get 2 pages instead of a small
sum). Can I get this result displayed as a sum?
Which version of Maxima do you use ?
Here is my session of Maxima with you equation differentiated wrt.a and than substituted to N=100.
~$ maxima
Maxima 5.24.0 http://maxima.sourceforge.net
using Lisp SBCL 1.0.51
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) sum((R[i]-(a*X[i]+b)*t + 1/2*(c*X[i]+d)^2*t)^2/((c*X[i]+d)^2*t), i, 1, N);
2
(c X + d) t
N i 2
==== (------------- - (a X + b) t + R )
\ 2 i i
> ------------------------------------
/ 2
==== (c X + d)
i = 1 i
(%o1) ------------------------------------------
t
(%i2) diff(%, a);
2
(c X + d) t
N i
==== X (------------- - (a X + b) t + R )
\ i 2 i i
(%o2) - 2 > --------------------------------------
/ 2
==== (c X + d)
i = 1 i
(%i3) %, N=100;
2
(c X + d) t
100 i
==== X (------------- - (a X + b) t + R )
\ i 2 i i
(%o3) - 2 > --------------------------------------
/ 2
==== (c X + d)
i = 1 i

How to define some variables as non-commutative in Maxima

For example, I'd like to define x and y as non-commutative, and a and b as commutative (as usual). In other words,
x y ≠ y x, a x = x a, a b = b a .
Further,
(x + a y) (x - a y) = x^2 + a (y x - x y) - a^2 y^2 .
What is a code for defining x and y, and a symbol for multiplication (such as * and . ) ?
You can work with Maxima's commutative * and non-commutative . products in the way that you want by following the next two steps:
Declare the symbols a and b as scalars:
declare([a, b], scalar)$
Enable dotscrules:
dotscrules: true$
This simplifies non-commutative products involving scalars to commutative products (i.e., a.x becomes a*x).
Now you are ready. For example,
expand((a*x + b*y) . (a*x - b*y))
returns
a*b*y.x - b^2*y^^2 - a*b*x.y + a^2*x^^2
(note that ^^ is the non-commutative exponentiation operator).

Implementing logical negation with only bitwise operators (except !)

~ & ^ | + << >> are the only operations I can use
Before I continue, this is a homework question, I've been stuck on this for a really long time.
My original approach: I thought that !x could be done with two's complement and doing something with it's additive inverse. I know that an xor is probably in here but I'm really at a loss how to approach this.
For the record: I also cannot use conditionals, loops, ==, etc, only the functions (bitwise) I mentioned above.
For example:
!0 = 1
!1 = 0
!anything besides 0 = 0
Assuming a 32 bit unsigned int:
(((x>>1) | (x&1)) + ~0U) >> 31
should do the trick
Assuming x is signed, need to return 0 for any number not zero, and 1 for zero.
A right shift on a signed integer usually is an arithmetical shift in most implementations (e.g. the sign bit is copied over). Therefore right shift x by 31 and its negation by 31. One of those two will be a negative number and so right shifted by 31 will be 0xFFFFFFFF (of course if x = 0 then the right shift will produce 0x0 which is what you want). You don't know if x or its negation is the negative number so just 'or' them together and you will get what you want. Next add 1 and your good.
implementation:
int bang(int x) {
return ((x >> 31) | ((~x + 1) >> 31)) + 1;
}
The following code copies any 1 bit to all positions. This maps all non-zeroes to 0xFFFFFFFF == -1, while leaving 0 at 0. Then it adds 1, mapping -1 to 0 and 0 to 1.
x = x | x << 1 | x >> 1
x = x | x << 2 | x >> 2
x = x | x << 4 | x >> 4
x = x | x << 8 | x >> 8
x = x | x << 16 | x >> 16
x = x + 1
For 32 bit signed integer x
// Set the bottom bit if any bit set.
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x ^= 1; // Toggle the bottom bit - now 0 if any bit set.
x &= 1; // Clear the unwanted bits to leave 0 or 1.
Assuming e.g. an 8-bit unsigned type:
~(((x >> 0) & 1)
| ((x >> 1) & 1)
| ((x >> 2) & 1)
...
| ((x >> 7) & 1)) & 1
You can just do ~x & 1 because it yields 1 for 0 and 0 for everything else

Resources