Condition checking gives wrong answer - c

#include <stdio.h>
int main(){
printf("%d,%d\n", 2 & (1<<1) , 2 & (1<<1)>0 );
return 0;
}
the output of this program is 2,0.
2 & (1<<1) is equal to 2 which is more than 0.
so why does 2 & (1<<1) > 0 evaluate to zero??

This expression
2 & (1<<1)>0
is equivalent to
2 & ( (1<<1)>0 )
due to the precedence of the operators. That is the relational operator > has a higher precedence than the bitwise AND operator. As 1 << 1 is greater than 0 then the sub-expression ( ( 1 << 1 ) > 0 ) yields the value 1.
So 2 & 1 yields 0 because in binary 1 can be represented (for simplicity) like 01 and 2 - like 10 and
01
&
10
---
00
It seems what you mean is the following expression
( 2 & ( 1 << 1 ) ) > 0

Related

How can I extract a hex digit n from word x?

getHexDigit - Extract hex digit n from word x
Digits numbered from 0 (least significant) to 7 (most significant)
Examples: getHexDigit(0x12345678,2) = 0x6
Legal ops: ! ~ & ^ | + << >>
I'm confused because I don't understand how to extract and write only using those ops. Please help!!
int getHexDigit(int x, int n) {
return (x >> (n >> 4)) & 0xff; // How do I fix this
}
A single digit corresponds to 4 bits, such that you have to shift n*4 bits right; So you have to multiply n by 4, and since you must not use n * 4, you can simply write n << 2; shifting two bits left means 2*2:
return (x >> (n << 2)) & 0x0F;
Then you have to "unmask" all the digits except the one you want to have; Therefore the & 0x0F.
This should do it:
int getHexDigit(int x, int n) {
return (x >> (n << 2)) & 0xf;
}
First, multiply n by 4 (by shifting left by 2-bits) because each hex digit is 4 bits, and then just take that group out by shifting right and masking with 0x0f.
For example, see how it works for getHexDigit(0x1234, 2):
bit pos 1 1 1 1 1 1
5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
(val) 1 2 3 4
x = 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0
n = 2
n << 2 = 4
(val) 0 1 2 3
x >> 4 = 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1
(val) 0 0 0 3
(x >> 4) & 0x0f = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1

Looking for clarity on this answer involving logical operations

I'm working on a homework problem and I already got the answer correct, but it was the result of adding operators out of frustration so I'm hoping someone can clarify this for me.
I'm testing to see if a number is positive or negative, return 1 if x > 0, return 0 otherwise. Only using the bit operations ! ~ & ^ | + << >>
Here's my answer: !(x >> 31 | !x)
When I work this out on paper my understanding of it falls apart.
move the sign bit all the way to the right
OR that bit with !x
positive would be 0 | 1
negative would be 1 | 0
! the result, which always, not matter what, ends up as 0
!(0 | 1) = 0
!(1 | 0) = 0
What am I understanding wrong?
Where you're off is in #2:
if x is positive, x >> 31 == 0 and !x == 0 so !(0 | 0) == 1
if x is negative, x >> 31 == 1 and !x == 0 so !(1 | 0) == 0
if x is zero, x >> 31 == 0 and !x == 1 so !(0 | 1) == 0
I think you're looking for :
size_t shift = sizeof(x) * 8 - 1;
bool ans = x | ~(1 << shift);

Compare "if between" with bitwise operators instead of logical

Okay i know this is a pretty mean task from which i got nightmares but maybe ..i'll crack that code thanks to someone of you.
I want to compare if number is between 0 and 10 with bitwise operators. Thats the thing.. it is between 0 and 10 and not for example between 0 and 2, 0 and 4, 0 and 8 and so on..
Reference for number/binary representation with 0-4 bits. (little endian)
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
Trying to figure out something like
if(((var & 4) >> var) + (var & 10))
I attempt to solve it with bitwise operators only (no addition).
The expression below will evaulate to nonzero if the number (v) is out of the 0 - 10 inclusive range:
(v & (~0xFU)) |
( ((v >> 3) & 1U) & ((v >> 2) & 1U) ) |
( ((v >> 3) & 1U) & ((v >> 1) & 1U) & (v & 1U) )
The first line is nonzero if the number is above 15 (any higher bit than the first four is set). The second line is nonzero if in the low 4 bits it is between 12 and 15 inclusive. The third line is nonzero if in the low 4 bits the number is either 11 or 15.
It was not clear in the question, but if the number to test is limited between the 0 - 15 inclusive range (only low 4 bits), then something nicer is possible here:
((~(v >> 3)) & 1U) |
( ((~(v >> 2)) & 1U) & (( ~v ) & 1U) ) |
( ((~(v >> 2)) & 1U) & ((~(v >> 1)) & 1U) )
First line is 1 if the number is between 0 and 7 inclusive. Second line is 1 if the number is one of 0, 2, 8 or 10. Third line is 1 if the number is one of 0, 1, 8 or 9. So OR combined the expression is 1 if the number is between 0 and 10 inclusive. Relating this solution, you may also check out the Karnaugh map, which can assist in generating these (and can also be used to prove there is no simpler solution here).
I don't think I could get any closer stricly using only bitwise operators in a reasonable manner. However if you can use addition it becomes a lot simpler as Pat's solution shows it.
Assuming that addition is allowed, then:
(v & ~0xf) | ((v+5) & ~0xf)
is non-zero if v is out-of-range. The first term tests if v is outside the range 0..15, and the second shifts the unwanted 11, 12, 13, 14, 15 outside the 0..15 range.
When addition is allowed and the range is 0..15, a simple solution is
(v - 11) & ~7
which is nonzero when v is in the range 0..10. Using shifts instead, you can use
(1<<10) >> v
which is also nonzero if the input is in the range 0..10. If the input range is unrestricted and the shift count is modulo 32, like on most CPUs, you can use
((1<<11) << ~v) | (v & ~15)
which is nonzero if the input is not in the range (the opposite is difficult since already v == 0 is difficult with only bitops). If other arithmetic operations are allowed, then
v / 11
can be used, which is also nonzero if the input is not in the range.
bool b1 = CheckCycleStateWithinRange(cycleState, 0b0, 0b1010); // Note *: 0b0 = 0 and 1010 = 10
bool CheckCycleStateWithinRange(int cycleState, int minRange, int maxRange) const
{
return ((IsGreaterThanEqual(cycleState, minRange) && IsLessThanEqual(cycleState, maxRange)) ? true : false );
}
int IsGreaterThanEqual(int cycleState, int limit) const
{
return ((limit + (~cycleState + 1)) >> 31 & 1) | (!(cycleState ^ limit));
}
int IsLessThanEqual(int cycleState, int limit) const
{
return !((limit + (~cycleState + 1)) >> 31 & 1) | (!(cycleState ^ limit));
}

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;

Bitwise & and I

Why is 1 & 4 = 0
whereas
1 | 4 evaluates to 5
Well.. because.
For &, the AND operator:
0001 = 1
0100 = 4
---- (AND)
0000 = 0
for |, the OR operator:
0001 = 1
0100 = 4
---- (OR)
0101 = 5
Bitwise & => If both bits are higher, then the output is higher else output is zero.
0 0 1
1 0 0
-----
0 0 0 => 0 // 1 & 1 = 1 , 1 & 0 = 0
Now try yourself Bitwise |. Any of the bit is higher, output is higher.
1 is 0b001, and 4 is 0b100, so, naturally, 1&4 is 0b000 and 1|4 is 0b101, which is 5.
Look at it in binary form.
1d(ecimal) = 001b(inary)
4d(ecimal) = 100b(inary)
thus
001b
100b & (both bits have to be 1 to yield 1)
--
000b = 0d
and
001b
100b | (only one on either side (or both) has to be 1 to yield 1)
--
101b = 5d

Resources