Bitwise C Operation - c

when x = 1
what should
! x | x
supposed to be?
I am really confused as what I did it:
x = 1 = 01 in binary,
!x = 10
!x | x = 11 = 3in decimal.
But it should be 1. (Even try going hexadecimal (something lengthy but what I am learning as an undergrad), I got -1)

The ! is the logical negation operator. If you give it nonzero things it gives you back a zero. If you give it a zero it gives you back 1.
So
!x | x
=> !1 | 1
=> 0 | 1
=> 1
Note how this is different from the bitwise negation operator, ~. If you had used this instead of !, things would have worked out like this (assuming 8-bit values, you can scale up to 32 or 64 or whatever):
~x | x
=> ~1 | 1
=> 11111110 | 00000001
=> 11111111
=> -1
It all comes down to understanding the difference between ! and ~. It's not obvious; it's just something you have to get used to. Just as a reminder
!7 = !23423523 = !46 = !(-200) = !1 = 0
For any nonzero x, !x = 0. That's just how it is. The idea behind that is C takes 0 as false and anything else as true. So, since a value like 70343 or 1 counts as true, applying ! to it gives false, or 0.

the ! operator is for logical negation, !x is equivalent to x == 0 for both numeric and pointer types.
!x has type int and a value of 1 if x compares equal to 0 and has a value of 0 for all other cases.

Related

Bitwise AND with 0 is unreachable in C

I want to check if the LSB is 0.
if(some_size_t & 1){} works fine
But why is if(some_size_t & 0){//This parts is unreachable} never reachable?
Because in order to ever get the value 1 i.e. true both operands for the logical and bitwise & i.e. AND operator have to be 1. Its so called truth table is
op1 | op2 | op1 AND op2
=====================
0 | 0 | 0
1 | 0 | 0
0 | 1 | 0
1 | 1 | 1
Because your value, e.g. op2, 0 has only zeros, no ones, you will always get only zeros as a result, no matter the other operand. And 0 will evaluate to false. It's what we call a contradiction in logic, often noted with a up side down T or \bot in latex.
As then the if condition is always false, the code in its body will never be executed, i.e. is unreachable.

~ Unary Operator and Bitwise Tests Give Negative Results

I was studying bitwise operators and they make sense until the unary ~one's complement is used with them. Can anyone explain to me how this works?
For example, these make sense however the rest of the computations aside from these do not:
1&~0 = 1 (~0 is 1 -> 1&1 = 1)
~0^~0 = 0 (~0 is 1 -> 1^1 = 0)
~1^0 = 1 (~1 is 0 -> 0^1 = 1)
~0&1 = 1 (~0 is 1 -> 1&1 = 1)
~0^~1 = 1 (~0 is 1, ~1 is 0 -> 1^0 = 1)
~1^~1 = 0 (~1 is 0 -> 0^0)
The rest of the results produced are negative(or a very large number if unsigned) or contradict the logic I am aware of. For example :
0&~1 = 0 (~1 = 0 therefor 0&0 should equal 0 but they equal 1)
~0&~1 = -2
~1|~0 = -1
etc. Anywhere you can point me to learn about this?
They actually do make sense when you expand them out a little more. A few things to be aware of though:
Bitwise AND yields a 1 only when both bits involved are 1. Otherwise, it yields 0. 1 & 1 = 1, 0 & anything = 0.
Bitwise OR yields a 1 when any of the bits in that position are a 1, and 0 only if all bits in that position are 0. 1 | 0 = 1, 1 | 1 = 1, 0 | 0 = 0.
Signed numbers are generally done as two's complement (though a processor does not have to do it that way!). Remember with two's complement, you invert and add 1 to get the magnitude when the highest bit position is a 1.
Assuming a 32-bit integer, you get these results:
0 & ~1 = 0 & 0xFFFFFFFE = 0
~0 & ~1 = 0xFFFFFFFF & 0xFFFFFFFE = 0xFFFFFFFE (0x00000001 + 1) = -2
~1 | ~0 = 0xFFFFFFFE & 0xFFFFFFFF = 0xFFFFFFFF (0x00000000 + 1) = -1
0&~1 = 0 (~1 = 0 therefor 0&0 should equal 0 but they equal 1)
~1 equals -2. If you flip all the bits of a Two's Complement number, you multiply it by -1 and subtract 1 from the result. Regardless of that 0 has 0 for all the bits, so the result of & is going to be 0 anyway.
~0&~1 = -2
~0 has all bits set so ~0&~1 is just ~1. Which is -2.
~1|~0 = -1
~0 has all bits set, so the result of the | is ~0 (= -1) no matter what it is OR'd with.
~1 = 0 - No it's not. It's equal to -2. Let's take a eight bit two complement as example. The decimal number 1 has the representation 0000 0001. So ~1 will have 1111 1110 which is the two complement representation of -2.

Why must I use the ~ operator when clearing a bit? [duplicate]

This question already has answers here:
How do I set, clear, and toggle a single bit?
(27 answers)
Closed 5 years ago.
For example, if I want to set a bit in y at position n (in C)
y = y | (1 << n)
But if I want to delete a bit in y at position n I have to use the ~ operator after binary AND.
y = y & ~(1 << n);
My question: Why Must I use the ~ operator?
Is this because the result turns into negative area?
If you want to set a bit at third place from the right :
Y : 01001000
1 << 2 : 00000100
Y | (1 << 2) : 01001100 The | is OR, bits are set to 1 if any is 1.
If you want to remove the bit :
1 << 2 : 00000100
~(1 << 2) : 11111011 The ~ is NOT, bits are inversed
Y : 01001100
Y & ~(1 << 2) : 01001000 The & is AND, bits are set to 1 if both are 1.
I suggest you read more about Bitwise operators
No, ~ has nothing to do with interpreting the number as negative: tilde ~ operator interprets the number as a pattern of bits, which it then inverts (i.e. replaces zeros with ones and ones with zeros). In fact, if you apply ~ to an unsigned value, the result would remain positive.
Recall that 1 << k expression produces a pattern of all zeros and a single 1 at the position designated by k. This is a bit mask that can be used to force bit at position k to 1 by applying OR operation.
Now consider what happens when you apply ~ to it: all 0s would become 1s, and the only 1 would become zero. Hence, the result is a bit mask suitable for forcing a single bit to zero by applying AND operation.
The ~ operator turns all of the 0's to 1's and all of the 1's to 0's. In order to clear the bint in position n you want to and it will all ones and a zero in the nth position so shift a one to the nth position and ~ invert all the bits.
1 << n for n==3 (just an example) gives you a pattern 0000000...0001000. ~ negates the bit
pattern to 11111111....11110111. Using the bitwise AND operator (&) will
only set the required bit to 0, all other remain with the same value. It's using
the fact that for a bit b: b & 1 == b.
~ flips all bits, it has nothing to do with negative numbers.
A graphical representation for a sequence of k-bits
pos k-1 k-2 0
+---+---+-------------------+---+---+
1: | 0 | 0 | ··· | 0 | 1 |
+---+---+-------------------+---+---+
pos k-1 k-2 n n-1 0
+---+---+-----+---+---+---+-----+---+
1<<n | 0 | 0 | ··· | 1 | 0 | 0 | ··· | 0 |
+---+---+-----+---+---+---+-----+---+
pos k-1 k-2 n n-1 0
+---+---+-----+---+---+---+-----+---+
~(1<<n) | 1 | 1 | ··· | 0 | 1 | 1 | ··· | 1 |
+---+---+-----+---+---+---+-----+---+

C Bit Operation Logic (bitAnd)

Background:
I stumbled across bitwise operators in C here, and now I am trying to learn more about them. I searched around for exercises and came across this.
However, I'm having trouble understanding the first one "bitAnd."
The code reads:
/*
* bitAnd - x&y using only ~ and |
* Example: bitAnd(6, 5) = 4
* Legal ops: ~ |
* Max ops: 8
* Rating: 1
*/
int bitAnd(int x, int y) {
/* NOR Equivelent of AND */
return ~(~x | ~y);
}
Question:
Now, I thought that the pipe ( | ) means "or." So, why do we need ~x and ~y? Can't we just say something like:
int bitAnd(int x, int y) {
int or = x | y; //something is one number or the other
int and = ~or; // not or is the same as and
return and;
}
I wrote and ran the second code sample for myself (I have a main function to run it). I get -8 as the answer, but with values 6 and 5, you should get 4.
If you have something for "or" (the pipe operator) and "and" is just the opposite or, why do we need to use "~" on each value before we calculate ~and?
Some extra information/thoughts:
I understand that "~" flips all the bits in the value. "Or" copies the bit from either value into the other if it exists (I learned that from here). So, if I have:
6 = 00000110
and
5 = 00000101
I should get 0000111.
I only mention that to show what knowledge I have of some of the operations in case my understanding of those are wrong as well.
This is typical logic gates knowledge. The equivalent of an AND gate is NOT of a NOR b.
Let's see what happens. Suppose you have values as such:
a = 00111 => 3
b = 01001 => 9
a AND b = 00001 => 1
This is what we expect. Let's run it through your shared method, the first one:
~a = 11000 => 24
~b = 10110 => 22
~a | ~b = 11110 => 30
~(~a | ~b) = 00001 => 1 as we expect.
Now, let's run your second proposed method.
or = 01111 => 15
and = ~or = 10000 => 16.
Now you have a problem. Logically, what you do is this:
~(a | b) = ~a AND ~b.
Is it really true though?
~a = 11000 => 24
~b = 10110 => 22
~a AND ~b = 10000 => 16.
It agrees with what I said above, however, it's wrong as you can see. We want 1, not 16. The bitwise inverse "~" operator is distributive. It inverts the operations as well. So an "or" becomes an "and" and an "and" becomes an "or". I hope that clears it up.
The solution you provided uses the de Morgan's rules, which say that not (A and B) = not A or not B. Since you need to compute A and B, you negate everything once more and you get: A and B = not (not (A and B)) = not (not A or not B).
Now, you can also think in terms of truth tables to see why this is true and why your claim isn't. I won't show everything in detail, but in your solution, not (A of B) when both A and B are 0, the result is 1, which is not consistent with the and operation.

Changing the LSB to 1 in a 4 bit integer via C

I am receiving a number N where N is a 4-bit integer and I need to change its LSB to 1 without changing the other 3 bits in the number using C.
Basically, all must read XXX1.
So lets say n = 2, the binary would be 0010. I would change the LSB to 1 making the number 0011.
I am struggling with finding a combination of operations that will do this. I am working with: !, ~, &, |, ^, <<, >>, +, -, =.
This has really been driving me crazy and I have been playing around with >>/<< and ~ and starting out with 0xF.
Try
number |= 1;
This should set the LSB to 1 regardless of what the number is. Why? Because the bitwise OR (|) operator does exactly what its name suggests: it logical ORs the two numbers' bits. So if you have, say, 1010b and 1b (10 and 1 in decimal), then the operator does this:
1 0 1 0
OR 0 0 0 1
= 1 0 1 1
And that's exactly what you want.
For your information, the
number |= 1;
statement is equivalent to
number = number | 1;
Use x = x | 0x01; to set the LSB to 1
A visualization
? ? ? ? ? ? ? ?
OR
0 0 0 0 0 0 0 1
----------------------
? ? ? ? ? ? ? 1
Therefore other bits will stay the same except the LSB is set to 1.
Use the bitwise or operator |. It looks at two numbers bit by bit, and returns the number generated by performing an OR with each bit.
int n = 2;
n = n | 1;
printf("%d\n", n); // prints the number 3
In binary, 2 = 0010, 3 = 0011, and 1 = 0001
0010
OR 0001
-------
0011
If n is not 0
n | !!n
works.
If n is 0, then !n is what you want.
UPDATE
The fancy one liner :P
n = n ? n | !!n : !n;

Resources